epydoc-3.0.1+dfsg/0002755000175000017500000000000010750103105014167 5ustar pronovicpronovicepydoc-3.0.1+dfsg/README.txt0000644000175000017500000000363710654406442015711 0ustar pronovicpronovic############################################################### ### Epydoc ### ###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~### ### Copyright (C) Edward Loper ### ### Author: Edward Loper ### ### URL: ### ### For license information, see LICENSE.TXT ### ############################################################### Introduction ~~~~~~~~~~~~ Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Documentation ~~~~~~~~~~~~~ Documentation for epydoc, including installation and usage instructions, and a complete description of the epytext markup language, is available on the epydoc homepage: This documentation is also available in the doc/ subdirectory of the source distribution. Installing ~~~~~~~~~~ To install epydoc, use make: [user epydoc-3.0]$ su Password: [root epydoc-3.0]# make install [root epydoc-3.0]# make installdocs Or use the distutils setup.py script: [user epydoc-3.0]$ su Password: [root epydoc-3.0]# python setup.py install For complete installation instructions, including instructions on how to install from RPM package, Debian package, or the windows installer, see the epydoc homepage: Usage ~~~~~ Run "epydoc --help" for a description of epydoc's usage. Contributing ~~~~~~~~~~~~ If you are interested in contributing to epydoc, please email . epydoc-3.0.1+dfsg/LICENSE.txt0000644000175000017500000000217010654406442016025 0ustar pronovicpronovicepydoc is released under the following license: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and any associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. epydoc-3.0.1+dfsg/Makefile0000644000175000017500000000503610654406442015646 0ustar pronovicpronovic############################################################ ## epydoc Makefile ## ## Edward Loper ############################################################ ##////////////////////////////////////////////////////////////////////// ## Configuration variables ##////////////////////////////////////////////////////////////////////// # Where do man pages and documentation go? LIB = /usr/share MAN = ${LIB}/man/ DOC = ${LIB}/doc/ # What version of python to use? PYTHON = python ##////////////////////////////////////////////////////////////////////// ## Makefile ##////////////////////////////////////////////////////////////////////// all: usage usage: @echo "Usage:" @echo " make install -- Install epydoc" @echo " make installdocs -- Install the documentation for epydoc" install: $(PYTHON) setup.py install docs: installdocs installdocs: @test -e ${MAN} || \ echo "Could not find ${MAN}; check the makefile variables." @test -e ${DOC} || \ echo "Could not find ${DOC}; check the makefile variables." @test -e ${MAN} @test -e ${DOC} test -e doc || ln -s ../webpage doc test -e man || ln -s ../man man cp man/*.1 ${MAN}/man1/ cp -r doc ${DOC}/epydoc/ ##////////////////////////////////////////////////////////////////////// ## These targets should only be called from ## the cvs repository (not from distributions). ##////////////////////////////////////////////////////////////////////// # Clean. # - Erase any pyc and pyo files. # - Get rid of build/dist directories clean: rm -rf build dist MANIFEST rm -f *.pyc epydoc/*.pyc epydoc/*/*.pyc rm -f *.pyo epydoc/*.pyo epydoc/*/*.pyo rm -f doc man 2>/dev/null || true # Distributions. # Build all from scratch; and create links for convenient access. distributions: clean sdist bdist # Source distributions sdist: gztardist zipdist # Built distributions bdist: rpmdist windist # Produce dist/$(NAME)-$(VERSION).tar.gz gztardist: test -e doc || ln -s ../webpage doc test -e man || ln -s ../man man $(PYTHON) setup.py -q sdist --format=gztar # Produce dist/$(NAME)-$(VERSION).tar.gz zipdist: test -e doc || ln -s ../webpage doc test -e man || ln -s ../man man $(PYTHON) setup.py -q sdist --format=zip # Produce dist/$(NAME)-$(VERSION)-1.noarch.rpm # Produce dist/$(NAME)-$(VERSION)-1.src.rpm rpmdist: test -e doc || ln -s ../webpage doc test -e man || ln -s ../man man $(PYTHON) setup.py -q bdist --format=rpm # Produce dist/$(NAME)-$(VERSION).win32.exe windist: test -e doc || ln -s ../webpage doc test -e man || ln -s ../man man $(PYTHON) setup.py -q bdist --format=wininst epydoc-3.0.1+dfsg/epydoc/0002755000175000017500000000000010750103105015452 5ustar pronovicpronovicepydoc-3.0.1+dfsg/epydoc/cli.py0000644000175000017500000016457210747624123016626 0ustar pronovicpronovic# epydoc -- Command line interface # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: cli.py 1678 2008-01-29 17:21:29Z edloper $ """ Command-line interface for epydoc. Abbreviated Usage:: epydoc [options] NAMES... NAMES... The Python modules to document. --html Generate HTML output (default). --latex Generate LaTeX output. --pdf Generate pdf output, via LaTeX. -o DIR, --output DIR The output directory. --inheritance STYLE The format for showing inherited objects. -V, --version Print the version of epydoc. -h, --help Display a usage message. Run \"epydoc --help\" for a complete option list. See the epydoc(1) man page for more information. Config Files ============ Configuration files can be specified with the C{--config} option. These files are read using U{ConfigParser }. Configuration files may set options or add names of modules to document. Option names are (usually) identical to the long names of command line options. To specify names to document, use any of the following option names:: module modules value values object objects A simple example of a config file is:: [epydoc] modules: sys, os, os.path, re, %(MYSANDBOXPATH)/utilities.py name: Example graph: classtree introspect: no All ConfigParser interpolations are done using local values and the environment variables. Verbosity Levels ================ The C{-v} and C{-q} options increase and decrease verbosity, respectively. The default verbosity level is zero. The verbosity levels are currently defined as follows:: Progress Markup warnings Warnings Errors -3 none no no no -2 none no no yes -1 none no yes yes 0 (default) bar no yes yes 1 bar yes yes yes 2 list yes yes yes """ __docformat__ = 'epytext en' import sys, os, time, re, pickle, textwrap from glob import glob from optparse import OptionParser, OptionGroup, SUPPRESS_HELP import optparse import epydoc from epydoc import log from epydoc.util import wordwrap, run_subprocess, RunSubprocessError from epydoc.util import plaintext_to_html from epydoc.apidoc import UNKNOWN from epydoc.compat import * import ConfigParser from epydoc.docwriter.html_css import STYLESHEETS as CSS_STYLESHEETS # This module is only available if Docutils are in the system try: from epydoc.docwriter import xlink except: xlink = None INHERITANCE_STYLES = ('grouped', 'listed', 'included') GRAPH_TYPES = ('classtree', 'callgraph', 'umlclasstree') ACTIONS = ('html', 'text', 'latex', 'dvi', 'ps', 'pdf', 'check') DEFAULT_DOCFORMAT = 'epytext' PROFILER = 'profile' #: Which profiler to use: 'hotshot' or 'profile' ###################################################################### #{ Help Topics ###################################################################### DOCFORMATS = ('epytext', 'plaintext', 'restructuredtext', 'javadoc') HELP_TOPICS = { 'docformat': textwrap.dedent('''\ __docformat__ is a module variable that specifies the markup language for the docstrings in a module. Its value is a string, consisting the name of a markup language, optionally followed by a language code (such as "en" for English). Epydoc currently recognizes the following markup language names: ''' + ', '.join(DOCFORMATS)), 'inheritance': textwrap.dedent('''\ The following inheritance formats are currently supported: - grouped: inherited objects are gathered into groups, based on what class they were inherited from. - listed: inherited objects are listed in a short list at the end of their section. - included: inherited objects are mixed in with non-inherited objects.'''), 'css': textwrap.dedent( 'The following built-in CSS stylesheets are available:\n' + '\n'.join([' %10s: %s' % (key, descr) for (key, (sheet, descr)) in CSS_STYLESHEETS.items()])), #'checks': textwrap.dedent('''\ # # '''), } HELP_TOPICS['topics'] = wordwrap( 'Epydoc can provide additional help for the following topics: ' + ', '.join(['%r' % topic for topic in HELP_TOPICS.keys()])) ###################################################################### #{ Argument & Config File Parsing ###################################################################### OPTION_DEFAULTS = dict( action="html", show_frames=True, docformat=DEFAULT_DOCFORMAT, show_private=True, show_imports=False, inheritance="listed", verbose=0, quiet=0, load_pickle=False, parse=True, introspect=True, debug=epydoc.DEBUG, profile=False, graphs=[], list_classes_separately=False, graph_font=None, graph_font_size=None, include_source_code=True, pstat_files=[], simple_term=False, fail_on=None, exclude=[], exclude_parse=[], exclude_introspect=[], external_api=[], external_api_file=[], external_api_root=[], redundant_details=False, src_code_tab_width=8) def parse_arguments(): # Construct the option parser. usage = '%prog [ACTION] [options] NAMES...' version = "Epydoc, version %s" % epydoc.__version__ optparser = OptionParser(usage=usage, add_help_option=False) optparser.add_option('--config', action='append', dest="configfiles", metavar='FILE', help=("A configuration file, specifying additional OPTIONS " "and/or NAMES. This option may be repeated.")) optparser.add_option("--output", "-o", dest="target", metavar="PATH", help="The output directory. If PATH does not exist, then " "it will be created.") optparser.add_option("--quiet", "-q", action="count", dest="quiet", help="Decrease the verbosity.") optparser.add_option("--verbose", "-v", action="count", dest="verbose", help="Increase the verbosity.") optparser.add_option("--debug", action="store_true", dest="debug", help="Show full tracebacks for internal errors.") optparser.add_option("--simple-term", action="store_true", dest="simple_term", help="Do not try to use color or cursor control when displaying " "the progress bar, warnings, or errors.") action_group = OptionGroup(optparser, 'Actions') optparser.add_option_group(action_group) action_group.add_option("--html", action="store_const", dest="action", const="html", help="Write HTML output.") action_group.add_option("--text", action="store_const", dest="action", const="text", help="Write plaintext output. (not implemented yet)") action_group.add_option("--latex", action="store_const", dest="action", const="latex", help="Write LaTeX output.") action_group.add_option("--dvi", action="store_const", dest="action", const="dvi", help="Write DVI output.") action_group.add_option("--ps", action="store_const", dest="action", const="ps", help="Write Postscript output.") action_group.add_option("--pdf", action="store_const", dest="action", const="pdf", help="Write PDF output.") action_group.add_option("--check", action="store_const", dest="action", const="check", help="Check completeness of docs.") action_group.add_option("--pickle", action="store_const", dest="action", const="pickle", help="Write the documentation to a pickle file.") # Provide our own --help and --version options. action_group.add_option("--version", action="store_const", dest="action", const="version", help="Show epydoc's version number and exit.") action_group.add_option("-h", "--help", action="store_const", dest="action", const="help", help="Show this message and exit. For help on specific " "topics, use \"--help TOPIC\". Use \"--help topics\" for a " "list of available help topics") generation_group = OptionGroup(optparser, 'Generation Options') optparser.add_option_group(generation_group) generation_group.add_option("--docformat", dest="docformat", metavar="NAME", help="The default markup language for docstrings. Defaults " "to \"%s\"." % DEFAULT_DOCFORMAT) generation_group.add_option("--parse-only", action="store_false", dest="introspect", help="Get all information from parsing (don't introspect)") generation_group.add_option("--introspect-only", action="store_false", dest="parse", help="Get all information from introspecting (don't parse)") generation_group.add_option("--exclude", dest="exclude", metavar="PATTERN", action="append", help="Exclude modules whose dotted name matches " "the regular expression PATTERN") generation_group.add_option("--exclude-introspect", dest="exclude_introspect", metavar="PATTERN", action="append", help="Exclude introspection of modules whose dotted name matches " "the regular expression PATTERN") generation_group.add_option("--exclude-parse", dest="exclude_parse", metavar="PATTERN", action="append", help="Exclude parsing of modules whose dotted name matches " "the regular expression PATTERN") generation_group.add_option("--inheritance", dest="inheritance", metavar="STYLE", help="The format for showing inheritance objects. STYLE " "should be one of: %s." % ', '.join(INHERITANCE_STYLES)) generation_group.add_option("--show-private", action="store_true", dest="show_private", help="Include private variables in the output. (default)") generation_group.add_option("--no-private", action="store_false", dest="show_private", help="Do not include private variables in the output.") generation_group.add_option("--show-imports", action="store_true", dest="show_imports", help="List each module's imports.") generation_group.add_option("--no-imports", action="store_false", dest="show_imports", help="Do not list each module's imports. (default)") generation_group.add_option('--show-sourcecode', action='store_true', dest='include_source_code', help=("Include source code with syntax highlighting in the " "HTML output. (default)")) generation_group.add_option('--no-sourcecode', action='store_false', dest='include_source_code', help=("Do not include source code with syntax highlighting in the " "HTML output.")) generation_group.add_option('--include-log', action='store_true', dest='include_log', help=("Include a page with the process log (epydoc-log.html)")) generation_group.add_option( '--redundant-details', action='store_true', dest='redundant_details', help=("Include values in the details lists even if all info " "about them is already provided by the summary table.")) output_group = OptionGroup(optparser, 'Output Options') optparser.add_option_group(output_group) output_group.add_option("--name", "-n", dest="prj_name", metavar="NAME", help="The documented project's name (for the navigation bar).") output_group.add_option("--css", "-c", dest="css", metavar="STYLESHEET", help="The CSS stylesheet. STYLESHEET can be either a " "builtin stylesheet or the name of a CSS file.") output_group.add_option("--url", "-u", dest="prj_url", metavar="URL", help="The documented project's URL (for the navigation bar).") output_group.add_option("--navlink", dest="prj_link", metavar="HTML", help="HTML code for a navigation link to place in the " "navigation bar.") output_group.add_option("--top", dest="top_page", metavar="PAGE", help="The \"top\" page for the HTML documentation. PAGE can " "be a URL, the name of a module or class, or one of the " "special names \"trees.html\", \"indices.html\", or \"help.html\"") output_group.add_option("--help-file", dest="help_file", metavar="FILE", help="An alternate help file. FILE should contain the body " "of an HTML file -- navigation bars will be added to it.") output_group.add_option("--show-frames", action="store_true", dest="show_frames", help="Include frames in the HTML output. (default)") output_group.add_option("--no-frames", action="store_false", dest="show_frames", help="Do not include frames in the HTML output.") output_group.add_option('--separate-classes', action='store_true', dest='list_classes_separately', help=("When generating LaTeX or PDF output, list each class in " "its own section, instead of listing them under their " "containing module.")) output_group.add_option('--src-code-tab-width', action='store', type='int', dest='src_code_tab_width', help=("When generating HTML output, sets the number of spaces " "each tab in source code listings is replaced with.")) # The group of external API options. # Skip if the module couldn't be imported (usually missing docutils) if xlink is not None: link_group = OptionGroup(optparser, xlink.ApiLinkReader.settings_spec[0]) optparser.add_option_group(link_group) for help, names, opts in xlink.ApiLinkReader.settings_spec[2]: opts = opts.copy() opts['help'] = help link_group.add_option(*names, **opts) graph_group = OptionGroup(optparser, 'Graph Options') optparser.add_option_group(graph_group) graph_group.add_option('--graph', action='append', dest='graphs', metavar='GRAPHTYPE', help=("Include graphs of type GRAPHTYPE in the generated output. " "Graphs are generated using the Graphviz dot executable. " "If this executable is not on the path, then use --dotpath " "to specify its location. This option may be repeated to " "include multiple graph types in the output. GRAPHTYPE " "should be one of: all, %s." % ', '.join(GRAPH_TYPES))) graph_group.add_option("--dotpath", dest="dotpath", metavar='PATH', help="The path to the Graphviz 'dot' executable.") graph_group.add_option('--graph-font', dest='graph_font', metavar='FONT', help=("Specify the font used to generate Graphviz graphs. (e.g., " "helvetica or times).")) graph_group.add_option('--graph-font-size', dest='graph_font_size', metavar='SIZE', help=("Specify the font size used to generate Graphviz graphs, " "in points.")) graph_group.add_option('--pstat', action='append', dest='pstat_files', metavar='FILE', help="A pstat output file, to be used in generating call graphs.") # this option is for developers, not users. graph_group.add_option("--profile-epydoc", action="store_true", dest="profile", help=SUPPRESS_HELP or ("Run the hotshot profiler on epydoc itself. Output " "will be written to profile.out.")) return_group = OptionGroup(optparser, 'Return Value Options') optparser.add_option_group(return_group) return_group.add_option("--fail-on-error", action="store_const", dest="fail_on", const=log.ERROR, help="Return a non-zero exit status, indicating failure, if any " "errors are encountered.") return_group.add_option("--fail-on-warning", action="store_const", dest="fail_on", const=log.WARNING, help="Return a non-zero exit status, indicating failure, if any " "errors or warnings are encountered (not including docstring " "warnings).") return_group.add_option("--fail-on-docstring-warning", action="store_const", dest="fail_on", const=log.DOCSTRING_WARNING, help="Return a non-zero exit status, indicating failure, if any " "errors or warnings are encountered (including docstring " "warnings).") # Set the option parser's defaults. optparser.set_defaults(**OPTION_DEFAULTS) # Parse the arguments. options, names = optparser.parse_args() # Print help message, if requested. We also provide support for # --help [topic] if options.action == 'help': names = set([n.lower() for n in names]) for (topic, msg) in HELP_TOPICS.items(): if topic.lower() in names: print '\n' + msg.rstrip() + '\n' sys.exit(0) optparser.print_help() sys.exit(0) # Print version message, if requested. if options.action == 'version': print version sys.exit(0) # Process any config files. if options.configfiles: try: parse_configfiles(options.configfiles, options, names) except (KeyboardInterrupt,SystemExit): raise except Exception, e: if len(options.configfiles) == 1: cf_name = 'config file %s' % options.configfiles[0] else: cf_name = 'config files %s' % ', '.join(options.configfiles) optparser.error('Error reading %s:\n %s' % (cf_name, e)) # Check if the input file is a pickle file. for name in names: if name.endswith('.pickle'): if len(names) != 1: optparser.error("When a pickle file is specified, no other " "input files may be specified.") options.load_pickle = True # Check to make sure all options are valid. if len(names) == 0: optparser.error("No names specified.") # perform shell expansion. for i, name in reversed(list(enumerate(names[:]))): if '?' in name or '*' in name: names[i:i+1] = glob(name) if options.inheritance not in INHERITANCE_STYLES: optparser.error("Bad inheritance style. Valid options are " + ",".join(INHERITANCE_STYLES)) if not options.parse and not options.introspect: optparser.error("Invalid option combination: --parse-only " "and --introspect-only.") if options.action == 'text' and len(names) > 1: optparser.error("--text option takes only one name.") # Check the list of requested graph types to make sure they're # acceptable. options.graphs = [graph_type.lower() for graph_type in options.graphs] for graph_type in options.graphs: if graph_type == 'callgraph' and not options.pstat_files: optparser.error('"callgraph" graph type may only be used if ' 'one or more pstat files are specified.') # If it's 'all', then add everything (but don't add callgraph if # we don't have any profiling info to base them on). if graph_type == 'all': if options.pstat_files: options.graphs = GRAPH_TYPES else: options.graphs = [g for g in GRAPH_TYPES if g != 'callgraph'] break elif graph_type not in GRAPH_TYPES: optparser.error("Invalid graph type %s." % graph_type) # Calculate verbosity. verbosity = getattr(options, 'verbosity', 0) options.verbosity = verbosity + options.verbose - options.quiet # The target default depends on the action. if options.target is None: options.target = options.action # Return parsed args. options.names = names return options, names def parse_configfiles(configfiles, options, names): configparser = ConfigParser.ConfigParser() # ConfigParser.read() silently ignores errors, so open the files # manually (since we want to notify the user of any errors). for configfile in configfiles: fp = open(configfile, 'r') # may raise IOError. configparser.readfp(fp, configfile) fp.close() for optname in configparser.options('epydoc'): val = configparser.get('epydoc', optname, vars=os.environ).strip() optname = optname.lower().strip() if optname in ('modules', 'objects', 'values', 'module', 'object', 'value'): names.extend(_str_to_list(val)) elif optname == 'target': options.target = val elif optname == 'output': if val.lower() not in ACTIONS: raise ValueError('"%s" expected one of: %s' % (optname, ', '.join(ACTIONS))) options.action = val.lower() elif optname == 'verbosity': options.verbosity = _str_to_int(val, optname) elif optname == 'debug': options.debug = _str_to_bool(val, optname) elif optname in ('simple-term', 'simple_term'): options.simple_term = _str_to_bool(val, optname) # Generation options elif optname == 'docformat': options.docformat = val elif optname == 'parse': options.parse = _str_to_bool(val, optname) elif optname == 'introspect': options.introspect = _str_to_bool(val, optname) elif optname == 'exclude': options.exclude.extend(_str_to_list(val)) elif optname in ('exclude-parse', 'exclude_parse'): options.exclude_parse.extend(_str_to_list(val)) elif optname in ('exclude-introspect', 'exclude_introspect'): options.exclude_introspect.extend(_str_to_list(val)) elif optname == 'inheritance': if val.lower() not in INHERITANCE_STYLES: raise ValueError('"%s" expected one of: %s.' % (optname, ', '.join(INHERITANCE_STYLES))) options.inheritance = val.lower() elif optname =='private': options.show_private = _str_to_bool(val, optname) elif optname =='imports': options.show_imports = _str_to_bool(val, optname) elif optname == 'sourcecode': options.include_source_code = _str_to_bool(val, optname) elif optname in ('include-log', 'include_log'): options.include_log = _str_to_bool(val, optname) elif optname in ('redundant-details', 'redundant_details'): options.redundant_details = _str_to_bool(val, optname) # Output options elif optname == 'name': options.prj_name = val elif optname == 'css': options.css = val elif optname == 'url': options.prj_url = val elif optname == 'link': options.prj_link = val elif optname == 'top': options.top_page = val elif optname == 'help': options.help_file = val elif optname =='frames': options.show_frames = _str_to_bool(val, optname) elif optname in ('separate-classes', 'separate_classes'): options.list_classes_separately = _str_to_bool(val, optname) elif optname in ('src-code-tab-width', 'src_code_tab_width'): options.src_code_tab_width = _str_to_int(val, optname) # External API elif optname in ('external-api', 'external_api'): options.external_api.extend(_str_to_list(val)) elif optname in ('external-api-file', 'external_api_file'): options.external_api_file.extend(_str_to_list(val)) elif optname in ('external-api-root', 'external_api_root'): options.external_api_root.extend(_str_to_list(val)) # Graph options elif optname == 'graph': graphtypes = _str_to_list(val) for graphtype in graphtypes: if graphtype not in GRAPH_TYPES + ('all',): raise ValueError('"%s" expected one of: all, %s.' % (optname, ', '.join(GRAPH_TYPES))) options.graphs.extend(graphtypes) elif optname == 'dotpath': options.dotpath = val elif optname in ('graph-font', 'graph_font'): options.graph_font = val elif optname in ('graph-font-size', 'graph_font_size'): options.graph_font_size = _str_to_int(val, optname) elif optname == 'pstat': options.pstat_files.extend(_str_to_list(val)) # Return value options elif optname in ('failon', 'fail-on', 'fail_on'): if val.lower().strip() in ('error', 'errors'): options.fail_on = log.ERROR elif val.lower().strip() in ('warning', 'warnings'): options.fail_on = log.WARNING elif val.lower().strip() in ('docstring_warning', 'docstring_warnings'): options.fail_on = log.DOCSTRING_WARNING else: raise ValueError("%r expected one of: error, warning, " "docstring_warning" % optname) else: raise ValueError('Unknown option %s' % optname) def _str_to_bool(val, optname): if val.lower() in ('0', 'no', 'false', 'n', 'f', 'hide'): return False elif val.lower() in ('1', 'yes', 'true', 'y', 't', 'show'): return True else: raise ValueError('"%s" option expected a boolean' % optname) def _str_to_int(val, optname): try: return int(val) except ValueError: raise ValueError('"%s" option expected an int' % optname) def _str_to_list(val): return val.replace(',', ' ').split() ###################################################################### #{ Interface ###################################################################### def main(options, names): # Set the debug flag, if '--debug' was specified. if options.debug: epydoc.DEBUG = True ## [XX] Did this serve a purpose? Commenting out for now: #if options.action == 'text': # if options.parse and options.introspect: # options.parse = False # Set up the logger if options.simple_term: TerminalController.FORCE_SIMPLE_TERM = True if options.action == 'text': logger = None # no logger for text output. elif options.verbosity > 1: logger = ConsoleLogger(options.verbosity) log.register_logger(logger) else: # Each number is a rough approximation of how long we spend on # that task, used to divide up the unified progress bar. stages = [40, # Building documentation 7, # Merging parsed & introspected information 1, # Linking imported variables 3, # Indexing documentation 1, # Checking for overridden methods 30, # Parsing Docstrings 1, # Inheriting documentation 2] # Sorting & Grouping if options.load_pickle: stages = [30] # Loading pickled documentation if options.action == 'html': stages += [100] elif options.action == 'text': stages += [30] elif options.action == 'latex': stages += [60] elif options.action == 'dvi': stages += [60,30] elif options.action == 'ps': stages += [60,40] elif options.action == 'pdf': stages += [60,50] elif options.action == 'check': stages += [10] elif options.action == 'pickle': stages += [10] else: raise ValueError, '%r not supported' % options.action if options.parse and not options.introspect: del stages[1] # no merging if options.introspect and not options.parse: del stages[1:3] # no merging or linking logger = UnifiedProgressConsoleLogger(options.verbosity, stages) log.register_logger(logger) # check the output directory. if options.action not in ('text', 'check', 'pickle'): if os.path.exists(options.target): if not os.path.isdir(options.target): log.error("%s is not a directory" % options.target) sys.exit(1) if options.include_log: if options.action == 'html': if not os.path.exists(options.target): os.mkdir(options.target) log.register_logger(HTMLLogger(options.target, options)) else: log.warning("--include-log requires --html") # Set the default docformat from epydoc import docstringparser docstringparser.DEFAULT_DOCFORMAT = options.docformat # Configure the external API linking if xlink is not None: try: xlink.ApiLinkReader.read_configuration(options, problematic=False) except Exception, exc: log.error("Error while configuring external API linking: %s: %s" % (exc.__class__.__name__, exc)) # Set the dot path if options.dotpath: from epydoc.docwriter import dotgraph dotgraph.DOT_COMMAND = options.dotpath # Set the default graph font & size if options.graph_font: from epydoc.docwriter import dotgraph fontname = options.graph_font dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontname'] = fontname dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontname'] = fontname if options.graph_font_size: from epydoc.docwriter import dotgraph fontsize = options.graph_font_size dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontsize'] = fontsize dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontsize'] = fontsize # If the input name is a pickle file, then read the docindex that # it contains. Otherwise, build the docs for the input names. if options.load_pickle: assert len(names) == 1 log.start_progress('Deserializing') log.progress(0.1, 'Loading %r' % names[0]) t0 = time.time() unpickler = pickle.Unpickler(open(names[0], 'rb')) unpickler.persistent_load = pickle_persistent_load docindex = unpickler.load() log.debug('deserialization time: %.1f sec' % (time.time()-t0)) log.end_progress() else: # Build docs for the named values. from epydoc.docbuilder import build_doc_index exclude_parse = '|'.join(options.exclude_parse+options.exclude) exclude_introspect = '|'.join(options.exclude_introspect+ options.exclude) docindex = build_doc_index(names, options.introspect, options.parse, add_submodules=(options.action!='text'), exclude_introspect=exclude_introspect, exclude_parse=exclude_parse) if docindex is None: if log.ERROR in logger.reported_message_levels: sys.exit(1) else: return # docbuilder already logged an error. # Load profile information, if it was given. if options.pstat_files: try: import pstats except ImportError: log.error("Could not import pstats -- ignoring pstat files.") try: profile_stats = pstats.Stats(options.pstat_files[0]) for filename in options.pstat_files[1:]: profile_stats.add(filename) except KeyboardInterrupt: raise except Exception, e: log.error("Error reading pstat file: %s" % e) profile_stats = None if profile_stats is not None: docindex.read_profiling_info(profile_stats) # Perform the specified action. if options.action == 'html': write_html(docindex, options) elif options.action in ('latex', 'dvi', 'ps', 'pdf'): write_latex(docindex, options, options.action) elif options.action == 'text': write_text(docindex, options) elif options.action == 'check': check_docs(docindex, options) elif options.action == 'pickle': write_pickle(docindex, options) else: print >>sys.stderr, '\nUnsupported action %s!' % options.action # If we suppressed docstring warnings, then let the user know. if logger is not None and logger.suppressed_docstring_warning: if logger.suppressed_docstring_warning == 1: prefix = '1 markup error was found' else: prefix = ('%d markup errors were found' % logger.suppressed_docstring_warning) log.warning("%s while processing docstrings. Use the verbose " "switch (-v) to display markup errors." % prefix) # Basic timing breakdown: if options.verbosity >= 2 and logger is not None: logger.print_times() # If we encountered any message types that we were requested to # fail on, then exit with status 2. if options.fail_on is not None: max_reported_message_level = max(logger.reported_message_levels) if max_reported_message_level >= options.fail_on: sys.exit(2) def write_html(docindex, options): from epydoc.docwriter.html import HTMLWriter html_writer = HTMLWriter(docindex, **options.__dict__) if options.verbose > 0: log.start_progress('Writing HTML docs to %r' % options.target) else: log.start_progress('Writing HTML docs') html_writer.write(options.target) log.end_progress() def write_pickle(docindex, options): """Helper for writing output to a pickle file, which can then be read in at a later time. But loading the pickle is only marginally faster than building the docs from scratch, so this has pretty limited application.""" if options.target == 'pickle': options.target = 'api.pickle' elif not options.target.endswith('.pickle'): options.target += '.pickle' log.start_progress('Serializing output') log.progress(0.2, 'Writing %r' % options.target) outfile = open(options.target, 'wb') pickler = pickle.Pickler(outfile, protocol=0) pickler.persistent_id = pickle_persistent_id pickler.dump(docindex) outfile.close() log.end_progress() def pickle_persistent_id(obj): """Helper for pickling, which allows us to save and restore UNKNOWN, which is required to be identical to apidoc.UNKNOWN.""" if obj is UNKNOWN: return 'UNKNOWN' else: return None def pickle_persistent_load(identifier): """Helper for pickling, which allows us to save and restore UNKNOWN, which is required to be identical to apidoc.UNKNOWN.""" if identifier == 'UNKNOWN': return UNKNOWN else: raise pickle.UnpicklingError, 'Invalid persistent id' _RERUN_LATEX_RE = re.compile(r'(?im)^LaTeX\s+Warning:\s+Label\(s\)\s+may' r'\s+have\s+changed.\s+Rerun') def write_latex(docindex, options, format): from epydoc.docwriter.latex import LatexWriter latex_writer = LatexWriter(docindex, **options.__dict__) log.start_progress('Writing LaTeX docs') latex_writer.write(options.target) log.end_progress() # If we're just generating the latex, and not any output format, # then we're done. if format == 'latex': return if format == 'dvi': steps = 4 elif format == 'ps': steps = 5 elif format == 'pdf': steps = 6 log.start_progress('Processing LaTeX docs') oldpath = os.path.abspath(os.curdir) running = None # keep track of what we're doing. try: try: os.chdir(options.target) # Clear any old files out of the way. for ext in 'tex aux log out idx ilg toc ind'.split(): if os.path.exists('apidoc.%s' % ext): os.remove('apidoc.%s' % ext) # The first pass generates index files. running = 'latex' log.progress(0./steps, 'LaTeX: First pass') run_subprocess('latex api.tex') # Build the index. running = 'makeindex' log.progress(1./steps, 'LaTeX: Build index') run_subprocess('makeindex api.idx') # The second pass generates our output. running = 'latex' log.progress(2./steps, 'LaTeX: Second pass') out, err = run_subprocess('latex api.tex') # The third pass is only necessary if the second pass # changed what page some things are on. running = 'latex' if _RERUN_LATEX_RE.match(out): log.progress(3./steps, 'LaTeX: Third pass') out, err = run_subprocess('latex api.tex') # A fourth path should (almost?) never be necessary. running = 'latex' if _RERUN_LATEX_RE.match(out): log.progress(3./steps, 'LaTeX: Fourth pass') run_subprocess('latex api.tex') # If requested, convert to postscript. if format in ('ps', 'pdf'): running = 'dvips' log.progress(4./steps, 'dvips') run_subprocess('dvips api.dvi -o api.ps -G0 -Ppdf') # If requested, convert to pdf. if format in ('pdf'): running = 'ps2pdf' log.progress(5./steps, 'ps2pdf') run_subprocess( 'ps2pdf -sPAPERSIZE#letter -dMaxSubsetPct#100 ' '-dSubsetFonts#true -dCompatibilityLevel#1.2 ' '-dEmbedAllFonts#true api.ps api.pdf') except RunSubprocessError, e: if running == 'latex': e.out = re.sub(r'(?sm)\A.*?!( LaTeX Error:)?', r'', e.out) e.out = re.sub(r'(?sm)\s*Type X to quit.*', '', e.out) e.out = re.sub(r'(?sm)^! Emergency stop.*', '', e.out) log.error("%s failed: %s" % (running, (e.out+e.err).lstrip())) except OSError, e: log.error("%s failed: %s" % (running, e)) finally: os.chdir(oldpath) log.end_progress() def write_text(docindex, options): log.start_progress('Writing output') from epydoc.docwriter.plaintext import PlaintextWriter plaintext_writer = PlaintextWriter() s = '' for apidoc in docindex.root: s += plaintext_writer.write(apidoc) log.end_progress() if isinstance(s, unicode): s = s.encode('ascii', 'backslashreplace') print s def check_docs(docindex, options): from epydoc.checker import DocChecker DocChecker(docindex).check() def cli(): # Parse command-line arguments. options, names = parse_arguments() try: try: if options.profile: _profile() else: main(options, names) finally: log.close() except SystemExit: raise except KeyboardInterrupt: print '\n\n' print >>sys.stderr, 'Keyboard interrupt.' except: if options.debug: raise print '\n\n' exc_info = sys.exc_info() if isinstance(exc_info[0], basestring): e = exc_info[0] else: e = exc_info[1] print >>sys.stderr, ('\nUNEXPECTED ERROR:\n' '%s\n' % (str(e) or e.__class__.__name__)) print >>sys.stderr, 'Use --debug to see trace information.' sys.exit(3) def _profile(): # Hotshot profiler. if PROFILER == 'hotshot': try: import hotshot, hotshot.stats except ImportError: print >>sys.stderr, "Could not import profile module!" return try: prof = hotshot.Profile('hotshot.out') prof = prof.runctx('main(*parse_arguments())', globals(), {}) except SystemExit: pass prof.close() # Convert profile.hotshot -> profile.out print 'Consolidating hotshot profiling info...' hotshot.stats.load('hotshot.out').dump_stats('profile.out') # Standard 'profile' profiler. elif PROFILER == 'profile': # cProfile module was added in Python 2.5 -- use it if its' # available, since it's faster. try: from cProfile import Profile except ImportError: try: from profile import Profile except ImportError: print >>sys.stderr, "Could not import profile module!" return # There was a bug in Python 2.4's profiler. Check if it's # present, and if so, fix it. (Bug was fixed in 2.4maint: # ) if (hasattr(Profile, 'dispatch') and Profile.dispatch['c_exception'] is Profile.trace_dispatch_exception.im_func): trace_dispatch_return = Profile.trace_dispatch_return.im_func Profile.dispatch['c_exception'] = trace_dispatch_return try: prof = Profile() prof = prof.runctx('main(*parse_arguments())', globals(), {}) except SystemExit: pass prof.dump_stats('profile.out') else: print >>sys.stderr, 'Unknown profiler %s' % PROFILER return ###################################################################### #{ Logging ###################################################################### class TerminalController: """ A class that can be used to portably generate formatted output to a terminal. See U{http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116} for documentation. (This is a somewhat stripped-down version.) """ BOL = '' #: Move the cursor to the beginning of the line UP = '' #: Move the cursor up one line DOWN = '' #: Move the cursor down one line LEFT = '' #: Move the cursor left one char RIGHT = '' #: Move the cursor right one char CLEAR_EOL = '' #: Clear to the end of the line. CLEAR_LINE = '' #: Clear the current line; cursor to BOL. BOLD = '' #: Turn on bold mode NORMAL = '' #: Turn off all modes COLS = 75 #: Width of the terminal (default to 75) BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' _STRING_CAPABILITIES = """ BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 CLEAR_EOL=el BOLD=bold UNDERLINE=smul NORMAL=sgr0""".split() _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() #: If this is set to true, then new TerminalControllers will #: assume that the terminal is not capable of doing manipulation #: of any kind. FORCE_SIMPLE_TERM = False def __init__(self, term_stream=sys.stdout): # If the stream isn't a tty, then assume it has no capabilities. if not term_stream.isatty(): return if self.FORCE_SIMPLE_TERM: return # Curses isn't available on all platforms try: import curses except: # If it's not available, then try faking enough to get a # simple progress bar. self.BOL = '\r' self.CLEAR_LINE = '\r' + ' '*self.COLS + '\r' # Check the terminal type. If we fail, then assume that the # terminal has no capabilities. try: curses.setupterm() except: return # Look up numeric capabilities. self.COLS = curses.tigetnum('cols') # Look up string capabilities. for capability in self._STRING_CAPABILITIES: (attrib, cap_name) = capability.split('=') setattr(self, attrib, self._tigetstr(cap_name) or '') if self.BOL and self.CLEAR_EOL: self.CLEAR_LINE = self.BOL+self.CLEAR_EOL # Colors set_fg = self._tigetstr('setf') if set_fg: for i,color in zip(range(len(self._COLORS)), self._COLORS): setattr(self, color, curses.tparm(set_fg, i) or '') set_fg_ansi = self._tigetstr('setaf') if set_fg_ansi: for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): setattr(self, color, curses.tparm(set_fg_ansi, i) or '') def _tigetstr(self, cap_name): # String capabilities can include "delays" of the form "$<2>". # For any modern terminal, we should be able to just ignore # these, so strip them out. import curses cap = curses.tigetstr(cap_name) or '' return re.sub(r'\$<\d+>[/*]?', '', cap) class ConsoleLogger(log.Logger): def __init__(self, verbosity, progress_mode=None): self._verbosity = verbosity self._progress = None self._message_blocks = [] # For ETA display: self._progress_start_time = None # For per-task times: self._task_times = [] self._progress_header = None self.reported_message_levels = set() """This set contains all the message levels (WARNING, ERROR, etc) that have been reported. It is used by the options --fail-on-warning etc to determine the return value.""" self.suppressed_docstring_warning = 0 """This variable will be incremented once every time a docstring warning is reported tothe logger, but the verbosity level is too low for it to be displayed.""" self.term = TerminalController() # Set the progress bar mode. if verbosity >= 2: self._progress_mode = 'list' elif verbosity >= 0: if progress_mode is not None: self._progress_mode = progress_mode elif self.term.COLS < 15: self._progress_mode = 'simple-bar' elif self.term.BOL and self.term.CLEAR_EOL and self.term.UP: self._progress_mode = 'multiline-bar' elif self.term.BOL and self.term.CLEAR_LINE: self._progress_mode = 'bar' else: self._progress_mode = 'simple-bar' else: self._progress_mode = 'hide' def start_block(self, header): self._message_blocks.append( (header, []) ) def end_block(self): header, messages = self._message_blocks.pop() if messages: width = self.term.COLS - 5 - 2*len(self._message_blocks) prefix = self.term.CYAN+self.term.BOLD+'| '+self.term.NORMAL divider = (self.term.CYAN+self.term.BOLD+'+'+'-'*(width-1)+ self.term.NORMAL) # Mark up the header: header = wordwrap(header, right=width-2, splitchars='\\/').rstrip() header = '\n'.join([prefix+self.term.CYAN+l+self.term.NORMAL for l in header.split('\n')]) # Construct the body: body = '' for message in messages: if message.endswith('\n'): body += message else: body += message+'\n' # Indent the body: body = '\n'.join([prefix+' '+l for l in body.split('\n')]) # Put it all together: message = divider + '\n' + header + '\n' + body + '\n' self._report(message) def _format(self, prefix, message, color): """ Rewrap the message; but preserve newlines, and don't touch any lines that begin with spaces. """ lines = message.split('\n') startindex = indent = len(prefix) for i in range(len(lines)): if lines[i].startswith(' '): lines[i] = ' '*(indent-startindex) + lines[i] + '\n' else: width = self.term.COLS - 5 - 4*len(self._message_blocks) lines[i] = wordwrap(lines[i], indent, width, startindex, '\\/') startindex = 0 return color+prefix+self.term.NORMAL+''.join(lines) def log(self, level, message): self.reported_message_levels.add(level) if self._verbosity >= -2 and level >= log.ERROR: message = self._format(' Error: ', message, self.term.RED) elif self._verbosity >= -1 and level >= log.WARNING: message = self._format('Warning: ', message, self.term.YELLOW) elif self._verbosity >= 1 and level >= log.DOCSTRING_WARNING: message = self._format('Warning: ', message, self.term.YELLOW) elif self._verbosity >= 3 and level >= log.INFO: message = self._format(' Info: ', message, self.term.NORMAL) elif epydoc.DEBUG and level == log.DEBUG: message = self._format(' Debug: ', message, self.term.CYAN) else: if level >= log.DOCSTRING_WARNING: self.suppressed_docstring_warning += 1 return self._report(message) def _report(self, message): if not message.endswith('\n'): message += '\n' if self._message_blocks: self._message_blocks[-1][-1].append(message) else: # If we're in the middle of displaying a progress bar, # then make room for the message. if self._progress_mode == 'simple-bar': if self._progress is not None: print self._progress = None if self._progress_mode == 'bar': sys.stdout.write(self.term.CLEAR_LINE) if self._progress_mode == 'multiline-bar': sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 + self.term.CLEAR_EOL + self.term.UP*2) # Display the message message. sys.stdout.write(message) sys.stdout.flush() def progress(self, percent, message=''): percent = min(1.0, percent) message = '%s' % message if self._progress_mode == 'list': if message: print '[%3d%%] %s' % (100*percent, message) sys.stdout.flush() elif self._progress_mode == 'bar': dots = int((self.term.COLS/2-8)*percent) background = '-'*(self.term.COLS/2-8) if len(message) > self.term.COLS/2: message = message[:self.term.COLS/2-3]+'...' sys.stdout.write(self.term.CLEAR_LINE + '%3d%% '%(100*percent) + self.term.GREEN + '[' + self.term.BOLD + '='*dots + background[dots:] + self.term.NORMAL + self.term.GREEN + '] ' + self.term.NORMAL + message + self.term.BOL) sys.stdout.flush() self._progress = percent elif self._progress_mode == 'multiline-bar': dots = int((self.term.COLS-10)*percent) background = '-'*(self.term.COLS-10) if len(message) > self.term.COLS-10: message = message[:self.term.COLS-10-3]+'...' else: message = message.center(self.term.COLS-10) time_elapsed = time.time()-self._progress_start_time if percent > 0: time_remain = (time_elapsed / percent) * (1-percent) else: time_remain = 0 sys.stdout.write( # Line 1: self.term.CLEAR_EOL + ' ' + '%-8s' % self._timestr(time_elapsed) + self.term.BOLD + 'Progress:'.center(self.term.COLS-26) + self.term.NORMAL + '%8s' % self._timestr(time_remain) + '\n' + # Line 2: self.term.CLEAR_EOL + ('%3d%% ' % (100*percent)) + self.term.GREEN + '[' + self.term.BOLD + '='*dots + background[dots:] + self.term.NORMAL + self.term.GREEN + ']' + self.term.NORMAL + '\n' + # Line 3: self.term.CLEAR_EOL + ' ' + message + self.term.BOL + self.term.UP + self.term.UP) sys.stdout.flush() self._progress = percent elif self._progress_mode == 'simple-bar': if self._progress is None: sys.stdout.write(' [') self._progress = 0.0 dots = int((self.term.COLS-2)*percent) progress_dots = int((self.term.COLS-2)*self._progress) if dots > progress_dots: sys.stdout.write('.'*(dots-progress_dots)) sys.stdout.flush() self._progress = percent def _timestr(self, dt): dt = int(dt) if dt >= 3600: return '%d:%02d:%02d' % (dt/3600, dt%3600/60, dt%60) else: return '%02d:%02d' % (dt/60, dt%60) def start_progress(self, header=None): if self._progress is not None: raise ValueError self._progress = None self._progress_start_time = time.time() self._progress_header = header if self._progress_mode != 'hide' and header: print self.term.BOLD + header + self.term.NORMAL def end_progress(self): self.progress(1.) if self._progress_mode == 'bar': sys.stdout.write(self.term.CLEAR_LINE) if self._progress_mode == 'multiline-bar': sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 + self.term.CLEAR_EOL + self.term.UP*2) if self._progress_mode == 'simple-bar': print ']' self._progress = None self._task_times.append( (time.time()-self._progress_start_time, self._progress_header) ) def print_times(self): print print 'Timing summary:' total = sum([time for (time, task) in self._task_times]) max_t = max([time for (time, task) in self._task_times]) for (time, task) in self._task_times: task = task[:31] print ' %s%s %7.1fs' % (task, '.'*(35-len(task)), time), if self.term.COLS > 55: print '|'+'=' * int((self.term.COLS-53) * time / max_t) else: print print class UnifiedProgressConsoleLogger(ConsoleLogger): def __init__(self, verbosity, stages, progress_mode=None): self.stage = 0 self.stages = stages self.task = None ConsoleLogger.__init__(self, verbosity, progress_mode) def progress(self, percent, message=''): #p = float(self.stage-1+percent)/self.stages i = self.stage-1 p = ((sum(self.stages[:i]) + percent*self.stages[i]) / float(sum(self.stages))) if message is UNKNOWN: message = None if message: message = '%s: %s' % (self.task, message) ConsoleLogger.progress(self, p, message) def start_progress(self, header=None): self.task = header if self.stage == 0: ConsoleLogger.start_progress(self) self.stage += 1 def end_progress(self): if self.stage == len(self.stages): ConsoleLogger.end_progress(self) def print_times(self): pass class HTMLLogger(log.Logger): """ A logger used to generate a log of all warnings and messages to an HTML file. """ FILENAME = "epydoc-log.html" HEADER = textwrap.dedent('''\ Epydoc Log

Epydoc Log

Epydoc started at %s

''') START_BLOCK = '

%s

' MESSAGE = ('
%s: \n' '%s
\n') END_BLOCK = '
' FOOTER = "\n\n" def __init__(self, directory, options): self.start_time = time.time() self.out = open(os.path.join(directory, self.FILENAME), 'w') self.out.write(self.HEADER % time.ctime(self.start_time)) self.is_empty = True self.options = options def write_options(self, options): self.out.write(self.START_BLOCK % 'Epydoc Options') msg = '\n' opts = [(key, getattr(options, key)) for key in dir(options) if key not in dir(optparse.Values)] opts = [(val==OPTION_DEFAULTS.get(key), key, val) for (key, val) in opts] for is_default, key, val in sorted(opts): css = is_default and 'opt-default' or 'opt-changed' msg += ('' '' '' % (css, key, plaintext_to_html(repr(val)))) msg += '
%s = %s
\n' self.out.write('
\n%s
\n' % msg) self.out.write(self.END_BLOCK) def start_block(self, header): self.out.write(self.START_BLOCK % header) def end_block(self): self.out.write(self.END_BLOCK) def log(self, level, message): if message.endswith("(-v) to display markup errors."): return if level >= log.ERROR: self.out.write(self._message('error', message)) elif level >= log.WARNING: self.out.write(self._message('warning', message)) elif level >= log.DOCSTRING_WARNING: self.out.write(self._message('docstring warning', message)) def _message(self, level, message): self.is_empty = False message = plaintext_to_html(message) if '\n' in message: message = '
%s
' % message hdr = ' '.join([w.capitalize() for w in level.split()]) return self.MESSAGE % (level.split()[-1], hdr, message) def close(self): if self.is_empty: self.out.write('
' 'No warnings or errors!
') self.write_options(self.options) self.out.write('

Epydoc finished at %s

\n' '

(Elapsed time: %s)

' % (time.ctime(), self._elapsed_time())) self.out.write(self.FOOTER) self.out.close() def _elapsed_time(self): secs = int(time.time()-self.start_time) if secs < 60: return '%d seconds' % secs if secs < 3600: return '%d minutes, %d seconds' % (secs/60, secs%60) else: return '%d hours, %d minutes' % (secs/3600, secs%3600) ###################################################################### ## main ###################################################################### if __name__ == '__main__': cli() epydoc-3.0.1+dfsg/epydoc/util.py0000644000175000017500000002353510747456557017043 0ustar pronovicpronovic# epydoc -- Utility functions # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: util.py 1671 2008-01-29 02:55:49Z edloper $ """ Miscellaneous utility functions that are used by multiple modules. @group Python source types: is_module_file, is_package_dir, is_pyname, py_src_filename @group Text processing: wordwrap, decode_with_backslashreplace, plaintext_to_html """ __docformat__ = 'epytext en' import os, os.path, re ###################################################################### ## Python Source Types ###################################################################### PY_SRC_EXTENSIONS = ['.py', '.pyw'] PY_BIN_EXTENSIONS = ['.pyc', '.so', '.pyd'] def is_module_file(path): # Make sure it's a file name. if not isinstance(path, basestring): return False (dir, filename) = os.path.split(path) (basename, extension) = os.path.splitext(filename) return (os.path.isfile(path) and re.match('[a-zA-Z_]\w*$', basename) and extension in PY_SRC_EXTENSIONS+PY_BIN_EXTENSIONS) def is_src_filename(filename): if not isinstance(filename, basestring): return False if not os.path.exists(filename): return False return os.path.splitext(filename)[1] in PY_SRC_EXTENSIONS def is_package_dir(dirname): """ Return true if the given directory is a valid package directory (i.e., it names a directory that contains a valid __init__ file, and its name is a valid identifier). """ # Make sure it's a directory name. if not isinstance(dirname, basestring): return False if not os.path.isdir(dirname): return False dirname = os.path.abspath(dirname) # Make sure it's a valid identifier. (Special case for # "foo/", where os.path.split -> ("foo", "").) (parent, dir) = os.path.split(dirname) if dir == '': (parent, dir) = os.path.split(parent) # The following constraint was removed because of sourceforge # bug #1787028 -- in some cases (eg eggs), it's too strict. #if not re.match('\w+$', dir): # return False for name in os.listdir(dirname): filename = os.path.join(dirname, name) if name.startswith('__init__.') and is_module_file(filename): return True else: return False def is_pyname(name): return re.match(r"\w+(\.\w+)*$", name) def py_src_filename(filename): basefile, extension = os.path.splitext(filename) if extension in PY_SRC_EXTENSIONS: return filename else: for ext in PY_SRC_EXTENSIONS: if os.path.isfile('%s%s' % (basefile, ext)): return '%s%s' % (basefile, ext) else: raise ValueError('Could not find a corresponding ' 'Python source file for %r.' % filename) def munge_script_name(filename): name = os.path.split(filename)[1] name = re.sub(r'\W', '_', name) return 'script-'+name ###################################################################### ## Text Processing ###################################################################### def decode_with_backslashreplace(s): r""" Convert the given 8-bit string into unicode, treating any character c such that ord(c)<128 as an ascii character, and converting any c such that ord(c)>128 into a backslashed escape sequence. >>> decode_with_backslashreplace('abc\xff\xe8') u'abc\\xff\\xe8' """ # s.encode('string-escape') is not appropriate here, since it # also adds backslashes to some ascii chars (eg \ and '). assert isinstance(s, str) return (s .decode('latin1') .encode('ascii', 'backslashreplace') .decode('ascii')) def wordwrap(str, indent=0, right=75, startindex=0, splitchars=''): """ Word-wrap the given string. I.e., add newlines to the string such that any lines that are longer than C{right} are broken into shorter lines (at the first whitespace sequence that occurs before index C{right}). If the given string contains newlines, they will I{not} be removed. Any lines that begin with whitespace will not be wordwrapped. @param indent: If specified, then indent each line by this number of spaces. @type indent: C{int} @param right: The right margin for word wrapping. Lines that are longer than C{right} will be broken at the first whitespace sequence before the right margin. @type right: C{int} @param startindex: If specified, then assume that the first line is already preceeded by C{startindex} characters. @type startindex: C{int} @param splitchars: A list of non-whitespace characters which can be used to split a line. (E.g., use '/\\' to allow path names to be split over multiple lines.) @rtype: C{str} """ if splitchars: chunks = re.split(r'( +|\n|[^ \n%s]*[%s])' % (re.escape(splitchars), re.escape(splitchars)), str.expandtabs()) else: chunks = re.split(r'( +|\n)', str.expandtabs()) result = [' '*(indent-startindex)] charindex = max(indent, startindex) for chunknum, chunk in enumerate(chunks): if (charindex+len(chunk) > right and charindex > 0) or chunk == '\n': result.append('\n' + ' '*indent) charindex = indent if chunk[:1] not in ('\n', ' '): result.append(chunk) charindex += len(chunk) else: result.append(chunk) charindex += len(chunk) return ''.join(result).rstrip()+'\n' def plaintext_to_html(s): """ @return: An HTML string that encodes the given plaintext string. In particular, special characters (such as C{'<'} and C{'&'}) are escaped. @rtype: C{string} """ s = s.replace('&', '&').replace('"', '"') s = s.replace('<', '<').replace('>', '>') return s def plaintext_to_latex(str, nbsp=0, breakany=0): """ @return: A LaTeX string that encodes the given plaintext string. In particular, special characters (such as C{'$'} and C{'_'}) are escaped, and tabs are expanded. @rtype: C{string} @param breakany: Insert hyphenation marks, so that LaTeX can break the resulting string at any point. This is useful for small boxes (e.g., the type box in the variable list table). @param nbsp: Replace every space with a non-breaking space (C{'~'}). """ # These get converted to hyphenation points later if breakany: str = re.sub('(.)', '\\1\1', str) # These get converted to \textbackslash later. str = str.replace('\\', '\0') # Expand tabs str = str.expandtabs() # These elements need to be backslashed. str = re.sub(r'([#$&%_\${}])', r'\\\1', str) # These elements have special names. str = str.replace('|', '{\\textbar}') str = str.replace('<', '{\\textless}') str = str.replace('>', '{\\textgreater}') str = str.replace('^', '{\\textasciicircum}') str = str.replace('~', '{\\textasciitilde}') str = str.replace('\0', r'{\textbackslash}') # replace spaces with non-breaking spaces if nbsp: str = str.replace(' ', '~') # Convert \1's to hyphenation points. if breakany: str = str.replace('\1', r'\-') return str class RunSubprocessError(OSError): def __init__(self, cmd, out, err): OSError.__init__(self, '%s failed' % cmd[0]) self.out = out self.err = err def run_subprocess(cmd, data=None): """ Execute the command C{cmd} in a subprocess. @param cmd: The command to execute, specified as a list of string. @param data: A string containing data to send to the subprocess. @return: A tuple C{(out, err)}. @raise OSError: If there is any problem executing the command, or if its exitval is not 0. """ if isinstance(cmd, basestring): cmd = cmd.split() # Under Python 2.4+, use subprocess try: from subprocess import Popen, PIPE pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) out, err = pipe.communicate(data) if hasattr(pipe, 'returncode'): if pipe.returncode == 0: return out, err else: raise RunSubprocessError(cmd, out, err) else: # Assume that there was an error iff anything was written # to the child's stderr. if err == '': return out, err else: raise RunSubprocessError(cmd, out, err) except ImportError: pass # Under Python 2.3 or earlier, on unix, use popen2.Popen3 so we # can access the return value. import popen2 if hasattr(popen2, 'Popen3'): pipe = popen2.Popen3(' '.join(cmd), True) to_child = pipe.tochild from_child = pipe.fromchild child_err = pipe.childerr if data: to_child.write(data) to_child.close() out = err = '' while pipe.poll() is None: out += from_child.read() err += child_err.read() out += from_child.read() err += child_err.read() if pipe.wait() == 0: return out, err else: raise RunSubprocessError(cmd, out, err) # Under Python 2.3 or earlier, on non-unix, use os.popen3 else: to_child, from_child, child_err = os.popen3(' '.join(cmd), 'b') if data: try: to_child.write(data) # Guard for a broken pipe error except IOError, e: raise OSError(e) to_child.close() out = from_child.read() err = child_err.read() # Assume that there was an error iff anything was written # to the child's stderr. if err == '': return out, err else: raise RunSubprocessError(cmd, out, err) epydoc-3.0.1+dfsg/epydoc/log.py0000644000175000017500000001563710654406440016632 0ustar pronovicpronovic# epydoc -- Logging # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: log.py 1488 2007-02-14 00:34:27Z edloper $ """ Functions used to report messages and progress updates to the user. These functions are delegated to zero or more registered L{Logger} objects, which are responsible for actually presenting the information to the user. Different interfaces are free to create and register their own C{Logger}s, allowing them to present this information in the manner that is best suited to each interface. @note: I considered using the standard C{logging} package to provide this functionality. However, I found that it would be too difficult to get that package to provide the behavior I want (esp. with respect to progress displays; but also with respect to message blocks). @group Message Severity Levels: DEBUG, INFO, WARNING, ERROR, FATAL """ __docformat__ = 'epytext en' import sys, os DEBUG = 10 INFO = 20 DOCSTRING_WARNING = 25 WARNING = 30 ERROR = 40 FATAL = 40 ###################################################################### # Logger Base Class ###################################################################### class Logger: """ An abstract base class that defines the interface for X{loggers}, which are used by epydoc to report information back to the user. Loggers are responsible for tracking two types of information: - Messages, such as warnings and errors. - Progress on the current task. This abstract class allows the command-line interface and the graphical interface to each present this information to the user in the way that's most natural for each interface. To set up a logger, create a subclass of C{Logger} that overrides all methods, and register it using L{register_logger}. """ #//////////////////////////////////////////////////////////// # Messages #//////////////////////////////////////////////////////////// def log(self, level, message): """ Display a message. @param message: The message string to display. C{message} may contain newlines, but does not need to end in a newline. @param level: An integer value indicating the severity of the message. """ def close(self): """ Perform any tasks needed to close this logger. """ #//////////////////////////////////////////////////////////// # Message blocks #//////////////////////////////////////////////////////////// def start_block(self, header): """ Start a new message block. Any calls to L{info()}, L{warning()}, or L{error()} that occur between a call to C{start_block} and a corresponding call to C{end_block} will be grouped together, and displayed with a common header. C{start_block} can be called multiple times (to form nested blocks), but every call to C{start_block} I{must} be balanced by a call to C{end_block}. """ def end_block(self): """ End a warning block. See L{start_block} for details. """ #//////////////////////////////////////////////////////////// # Progress bar #//////////////////////////////////////////////////////////// def start_progress(self, header=None): """ Begin displaying progress for a new task. C{header} is a description of the task for which progress is being reported. Each call to C{start_progress} must be followed by a call to C{end_progress} (with no intervening calls to C{start_progress}). """ def end_progress(self): """ Finish off the display of progress for the current task. See L{start_progress} for more information. """ def progress(self, percent, message=''): """ Update the progress display. @param percent: A float from 0.0 to 1.0, indicating how much progress has been made. @param message: A message indicating the most recent action that contributed towards that progress. """ class SimpleLogger(Logger): def __init__(self, threshold=WARNING): self.threshold = threshold def log(self, level, message): if level >= self.threshold: print message ###################################################################### # Logger Registry ###################################################################### _loggers = [] """ The list of registered logging functions. """ def register_logger(logger): """ Register a logger. Each call to one of the logging functions defined by this module will be delegated to each registered logger. """ _loggers.append(logger) def remove_logger(logger): _loggers.remove(logger) ###################################################################### # Logging Functions ###################################################################### # The following methods all just delegate to the corresponding # methods in the Logger class (above) for each registered logger. def fatal(*messages): """Display the given fatal message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(FATAL, message) def error(*messages): """Display the given error message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(ERROR, message) def warning(*messages): """Display the given warning message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(WARNING, message) def docstring_warning(*messages): """Display the given docstring warning message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(DOCSTRING_WARNING, message) def info(*messages): """Display the given informational message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(INFO, message) def debug(*messages): """Display the given debugging message.""" message = ' '.join(['%s' % (m,) for m in messages]) for logger in _loggers: logger.log(DEBUG, message) def start_block(header): for logger in _loggers: logger.start_block(header) start_block.__doc__ = Logger.start_block.__doc__ def end_block(): for logger in _loggers: logger.end_block() end_block.__doc__ = Logger.end_block.__doc__ def start_progress(header=None): for logger in _loggers: logger.start_progress(header) start_progress.__doc__ = Logger.start_progress.__doc__ def end_progress(): for logger in _loggers: logger.end_progress() end_progress.__doc__ = Logger.end_progress.__doc__ def progress(percent, message=''): for logger in _loggers: logger.progress(percent, '%s' % message) progress.__doc__ = Logger.progress.__doc__ def close(): for logger in _loggers: logger.close() epydoc-3.0.1+dfsg/epydoc/gui.py0000644000175000017500000013355110750073107016626 0ustar pronovicpronovic#!/usr/bin/env python # # objdoc: epydoc command-line interface # Edward Loper # # Created [03/15/02 10:31 PM] # $Id: gui.py 646 2004-03-19 19:01:37Z edloper $ # """ Graphical interface to epydoc. This interface might be useful for systems where it's inconvenient to use the command-line interface (such as Windows). It supports many (but not all) of the features that are supported by the command-line interface. It also supports loading and saving of X{project files}, which store a set of related modules, and the options that should be used to generate the documentation for those modules. Usage:: epydocgui [OPTIONS] [FILE.prj | MODULES...] FILE.prj An epydoc GUI project file. MODULES... A list of Python modules to document. -V, --version Print the version of epydoc. -h, -?, --help, --usage Display this usage message --debug Do not suppress error messages @todo: Use ini-style project files, rather than pickles (using the same format as the CLI). """ __docformat__ = 'epytext en' import sys, os.path, re, glob from Tkinter import * from tkFileDialog import askopenfilename, asksaveasfilename from thread import start_new_thread, exit_thread from pickle import dump, load # askdirectory is only defined in python 2.2+; fall back on # asksaveasfilename if it's not available. try: from tkFileDialog import askdirectory except: askdirectory = None # Include support for Zope, if it's available. try: import ZODB except: pass ##///////////////////////////////////////////////////////////////////////// ## CONSTANTS ##///////////////////////////////////////////////////////////////////////// DEBUG = 0 # Colors for tkinter display BG_COLOR='#e0e0e0' ACTIVEBG_COLOR='#e0e0e0' TEXT_COLOR='black' ENTRYSELECT_COLOR = ACTIVEBG_COLOR SELECT_COLOR = '#208070' MESSAGE_COLOR = '#000060' ERROR_COLOR = '#600000' GUIERROR_COLOR = '#600000' WARNING_COLOR = '#604000' HEADER_COLOR = '#000000' # Convenience dictionaries for specifying widget colors COLOR_CONFIG = {'background':BG_COLOR, 'highlightcolor': BG_COLOR, 'foreground':TEXT_COLOR, 'highlightbackground': BG_COLOR} ENTRY_CONFIG = {'background':BG_COLOR, 'highlightcolor': BG_COLOR, 'foreground':TEXT_COLOR, 'highlightbackground': BG_COLOR, 'selectbackground': ENTRYSELECT_COLOR, 'selectforeground': TEXT_COLOR} SB_CONFIG = {'troughcolor':BG_COLOR, 'activebackground':BG_COLOR, 'background':BG_COLOR, 'highlightbackground':BG_COLOR} LISTBOX_CONFIG = {'highlightcolor': BG_COLOR, 'highlightbackground': BG_COLOR, 'foreground':TEXT_COLOR, 'selectforeground': TEXT_COLOR, 'selectbackground': ACTIVEBG_COLOR, 'background':BG_COLOR} BUTTON_CONFIG = {'background':BG_COLOR, 'highlightthickness':0, 'padx':4, 'highlightbackground': BG_COLOR, 'foreground':TEXT_COLOR, 'highlightcolor': BG_COLOR, 'activeforeground': TEXT_COLOR, 'activebackground': ACTIVEBG_COLOR, 'pady':0} CBUTTON_CONFIG = {'background':BG_COLOR, 'highlightthickness':0, 'padx':4, 'highlightbackground': BG_COLOR, 'foreground':TEXT_COLOR, 'highlightcolor': BG_COLOR, 'activeforeground': TEXT_COLOR, 'activebackground': ACTIVEBG_COLOR, 'pady':0, 'selectcolor': SELECT_COLOR} SHOWMSG_CONFIG = CBUTTON_CONFIG.copy() SHOWMSG_CONFIG['foreground'] = MESSAGE_COLOR SHOWWRN_CONFIG = CBUTTON_CONFIG.copy() SHOWWRN_CONFIG['foreground'] = WARNING_COLOR SHOWERR_CONFIG = CBUTTON_CONFIG.copy() SHOWERR_CONFIG['foreground'] = ERROR_COLOR # Colors for the progress bar PROGRESS_HEIGHT = 16 PROGRESS_WIDTH = 200 PROGRESS_BG='#305060' PROGRESS_COLOR1 = '#30c070' PROGRESS_COLOR2 = '#60ffa0' PROGRESS_COLOR3 = '#106030' # On tkinter canvases, where's the zero coordinate? if sys.platform.lower().startswith('win'): DX = 3; DY = 3 DH = 0; DW = 7 else: DX = 1; DY = 1 DH = 1; DW = 3 # How much of the progress is in each subtask? IMPORT_PROGRESS = 0.1 BUILD_PROGRESS = 0.2 WRITE_PROGRESS = 1.0 - BUILD_PROGRESS - IMPORT_PROGRESS ##///////////////////////////////////////////////////////////////////////// ## IMAGE CONSTANTS ##///////////////////////////////////////////////////////////////////////// UP_GIF = '''\ R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAACH5BAEAAAAALAAAAAALAAwAAAQjEMhJKxCW4gzCIJxXZIEwFGDlDadqsii1sq1U0nA64+ON 5xEAOw== ''' DOWN_GIF = '''\ R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAACH5BAEAAAAALAAAAAALAAwAAAQmEIQxgLVUCsppsVPngVtXEFfIfWk5nBe4xuSL0tKLy/cu 7JffJQIAOw== ''' LEFT_GIF='''\ R0lGODlhDAALAKIAANnZ2QDMmQCZZgBmZgAAAAAzM////////yH5BAEAAAAALAAAAAAMAAsAAAM4 CLocgaCrESiDoBshOAoAgBEyMzgAEIGCowsiOLoLgEBVOLoIqlSFo4OgC1RYM4Ogq1RYg6DLVJgA Ow== ''' RIGHT_GIF='''\ R0lGODlhDAALAKIAANnZ2QDMmQBmZgCZZgAzMwAAAP///////yH5BAEAAAAALAAAAAAMAAsAAAM5 GIGgyzIYgaCrIigTgaALIigyEQiqKLoTgaAoujuDgKJLVAgqIoJEBQAIIkKEhaArRFgIukqFoMsJ ADs= ''' ##///////////////////////////////////////////////////////////////////////// ## MessageIO ##///////////////////////////////////////////////////////////////////////// from epydoc import log from epydoc.util import wordwrap class GUILogger(log.Logger): _STAGES = [40, 7, 1, 3, 1, 30, 1, 2, 100] def __init__(self, progress, cancel): self._progress = progress self._cancel = cancel self.clear() def clear(self): self._messages = [] self._n = 0 self._stage = 0 self._message_blocks = [] def log(self, level, message): message = wordwrap(str(message)).rstrip() + '\n' if self._message_blocks: self._message_blocks[-1][-1].append( (level, message) ) else: self._messages.append( (level, message) ) def start_block(self, header): self._message_blocks.append( (header, []) ) def end_block(self): header, messages = self._message_blocks.pop() if messages: self._messages.append( ('uline', ' '*75+'\n') ) self.log('header', header) self._messages += messages self._messages.append( ('uline', ' '*75+'\n') ) def start_progress(self, header=None): self.log(log.INFO, header) self._stage += 1 def end_progress(self): pass def progress(self, percent, message=''): if self._cancel[0]: exit_thread() i = self._stage - 1 p = ((sum(self._STAGES[:i]) + percent*self._STAGES[i]) / float(sum(self._STAGES))) self._progress[0] = p def read(self): if self._n >= len(self._messages): return None, None else: self._n += 1 return self._messages[self._n-1] ##///////////////////////////////////////////////////////////////////////// ## THREADED DOCUMENTER ##///////////////////////////////////////////////////////////////////////// def document(options, cancel, done): """ Create the documentation for C{modules}, using the options specified by C{options}. C{document} is designed to be started in its own thread by L{EpydocGUI._go}. @param options: The options to use for generating documentation. This includes keyword options that can be given to L{docwriter.html.HTMLWriter}, as well as the option C{target}, which controls where the output is written to. @type options: C{dictionary} """ from epydoc.docwriter.html import HTMLWriter from epydoc.docbuilder import build_doc_index import epydoc.docstringparser # Set the default docformat. docformat = options.get('docformat', 'epytext') epydoc.docstringparser.DEFAULT_DOCFORMAT = docformat try: parse = options['introspect_or_parse'] in ('parse', 'both') introspect = options['introspect_or_parse'] in ('introspect', 'both') docindex = build_doc_index(options['modules'], parse, introspect) html_writer = HTMLWriter(docindex, **options) log.start_progress('Writing HTML docs to %r' % options['target']) html_writer.write(options['target']) log.end_progress() # We're done. log.warning('Finished!') done[0] = 'done' except SystemExit: # Cancel. log.error('Cancelled!') done[0] ='cancel' raise except Exception, e: # We failed. log.error('Internal error: %s' % e) done[0] ='cancel' raise except: # We failed. log.error('Internal error!') done[0] ='cancel' raise ##///////////////////////////////////////////////////////////////////////// ## GUI ##///////////////////////////////////////////////////////////////////////// class EpydocGUI: """ A graphical user interace to epydoc. """ def __init__(self): self._afterid = 0 self._progress = [None] self._cancel = [0] self._filename = None self._init_dir = None # Store a copy of sys.modules, so that we can restore it # later. This is useful for making sure that we reload # everything when we re-build its documentation. This will # *not* reload the modules that are present when the EpydocGUI # is created, but that should only contain some builtins, some # epydoc modules, Tkinter, pickle, and thread.. self._old_modules = sys.modules.keys() # Create the main window. self._root = Tk() self._root['background']=BG_COLOR self._root.bind('', self.destroy) self._root.bind('', self.destroy) self._root.bind('', self.destroy) self._root.bind('', self.destroy) #self._root.bind('', self.destroy) self._root.title('Epydoc') self._rootframe = Frame(self._root, background=BG_COLOR, border=2, relief='raised') self._rootframe.pack(expand=1, fill='both', padx=2, pady=2) # Set up the basic frames. Do not pack the options frame or # the messages frame; the GUI has buttons to expand them. leftframe = Frame(self._rootframe, background=BG_COLOR) leftframe.pack(expand=1, fill='both', side='left') optsframe = Frame(self._rootframe, background=BG_COLOR) mainframe = Frame(leftframe, background=BG_COLOR) mainframe.pack(expand=1, fill='both', side='top') ctrlframe = Frame(mainframe, background=BG_COLOR) ctrlframe.pack(side="bottom", fill='x', expand=0) msgsframe = Frame(leftframe, background=BG_COLOR) self._optsframe = optsframe self._msgsframe = msgsframe # Initialize all the frames, etc. self._init_menubar() self._init_progress_bar(mainframe) self._init_module_list(mainframe) self._init_options(optsframe, ctrlframe) self._init_messages(msgsframe, ctrlframe) self._init_bindings() # Set up logging self._logger = GUILogger(self._progress, self._cancel) log.register_logger(self._logger) # Open the messages pane by default. self._messages_toggle() ## For testing options: #self._options_toggle() def _init_menubar(self): menubar = Menu(self._root, borderwidth=2, background=BG_COLOR, activebackground=BG_COLOR) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label='New Project', underline=0, command=self._new, accelerator='Ctrl-n') filemenu.add_command(label='Open Project', underline=0, command=self._open, accelerator='Ctrl-o') filemenu.add_command(label='Save Project', underline=0, command=self._save, accelerator='Ctrl-s') filemenu.add_command(label='Save As..', underline=5, command=self._saveas, accelerator='Ctrl-a') filemenu.add_separator() filemenu.add_command(label='Exit', underline=1, command=self.destroy, accelerator='Ctrl-x') menubar.add_cascade(label='File', underline=0, menu=filemenu) gomenu = Menu(menubar, tearoff=0) gomenu.add_command(label='Run Epydoc', command=self._open, underline=0, accelerator='Alt-g') menubar.add_cascade(label='Run', menu=gomenu, underline=0) self._root.config(menu=menubar) def _init_module_list(self, mainframe): mframe1 = Frame(mainframe, relief='groove', border=2, background=BG_COLOR) mframe1.pack(side="top", fill='both', expand=1, padx=4, pady=3) l = Label(mframe1, text="Modules to document:", justify='left', **COLOR_CONFIG) l.pack(side='top', fill='none', anchor='nw', expand=0) mframe2 = Frame(mframe1, background=BG_COLOR) mframe2.pack(side="top", fill='both', expand=1) mframe3 = Frame(mframe1, background=BG_COLOR) mframe3.pack(side="bottom", fill='x', expand=0) self._module_list = Listbox(mframe2, width=80, height=10, selectmode='multiple', **LISTBOX_CONFIG) self._module_list.pack(side="left", fill='both', expand=1) sb = Scrollbar(mframe2, orient='vertical',**SB_CONFIG) sb['command']=self._module_list.yview sb.pack(side='right', fill='y') self._module_list.config(yscrollcommand=sb.set) Label(mframe3, text="Add:", **COLOR_CONFIG).pack(side='left') self._module_entry = Entry(mframe3, **ENTRY_CONFIG) self._module_entry.pack(side='left', fill='x', expand=1) self._module_entry.bind('', self._entry_module) self._module_delete = Button(mframe3, text="Remove", command=self._delete_module, **BUTTON_CONFIG) self._module_delete.pack(side='right', expand=0, padx=2) self._module_browse = Button(mframe3, text="Browse", command=self._browse_module, **BUTTON_CONFIG) self._module_browse.pack(side='right', expand=0, padx=2) def _init_progress_bar(self, mainframe): pframe1 = Frame(mainframe, background=BG_COLOR) pframe1.pack(side="bottom", fill='x', expand=0) self._go_button = Button(pframe1, width=4, text='Start', underline=0, command=self._go, **BUTTON_CONFIG) self._go_button.pack(side='left', padx=4) pframe2 = Frame(pframe1, relief='groove', border=2, background=BG_COLOR) pframe2.pack(side="top", fill='x', expand=1, padx=4, pady=3) Label(pframe2, text='Progress:', **COLOR_CONFIG).pack(side='left') H = self._H = PROGRESS_HEIGHT W = self._W = PROGRESS_WIDTH c = self._canvas = Canvas(pframe2, height=H+DH, width=W+DW, background=PROGRESS_BG, border=0, selectborderwidth=0, relief='sunken', insertwidth=0, insertborderwidth=0, highlightbackground=BG_COLOR) self._canvas.pack(side='left', fill='x', expand=1, padx=4) self._r2 = c.create_rectangle(0,0,0,0, outline=PROGRESS_COLOR2) self._r3 = c.create_rectangle(0,0,0,0, outline=PROGRESS_COLOR3) self._r1 = c.create_rectangle(0,0,0,0, fill=PROGRESS_COLOR1, outline='') self._canvas.bind('', self._configure) def _init_messages(self, msgsframe, ctrlframe): self._downImage = PhotoImage(master=self._root, data=DOWN_GIF) self._upImage = PhotoImage(master=self._root, data=UP_GIF) # Set up the messages control frame b1 = Button(ctrlframe, text="Messages", justify='center', command=self._messages_toggle, underline=0, highlightthickness=0, activebackground=BG_COLOR, border=0, relief='flat', padx=2, pady=0, **COLOR_CONFIG) b2 = Button(ctrlframe, image=self._downImage, relief='flat', border=0, command=self._messages_toggle, activebackground=BG_COLOR, **COLOR_CONFIG) self._message_button = b2 self._messages_visible = 0 b2.pack(side="left") b1.pack(side="left") f = Frame(msgsframe, background=BG_COLOR) f.pack(side='top', expand=1, fill='both') messages = Text(f, width=80, height=10, **ENTRY_CONFIG) messages['state'] = 'disabled' messages.pack(fill='both', expand=1, side='left') self._messages = messages # Add a scrollbar sb = Scrollbar(f, orient='vertical', **SB_CONFIG) sb.pack(fill='y', side='right') sb['command'] = messages.yview messages['yscrollcommand'] = sb.set # Set up some colorization tags messages.tag_config('error', foreground=ERROR_COLOR) messages.tag_config('warning', foreground=WARNING_COLOR) messages.tag_config('guierror', foreground=GUIERROR_COLOR) messages.tag_config('message', foreground=MESSAGE_COLOR) messages.tag_config('header', foreground=HEADER_COLOR) messages.tag_config('uline', underline=1) # Keep track of tag state.. self._in_header = 0 self._last_tag = 'error' # Add some buttons buttons = Frame(msgsframe, background=BG_COLOR) buttons.pack(side='bottom', fill='x') self._show_errors = IntVar(self._root) self._show_errors.set(1) self._show_warnings = IntVar(self._root) self._show_warnings.set(1) self._show_messages = IntVar(self._root) self._show_messages.set(0) Checkbutton(buttons, text='Show Messages', var=self._show_messages, command=self._update_msg_tags, **SHOWMSG_CONFIG).pack(side='left') Checkbutton(buttons, text='Show Warnings', var=self._show_warnings, command=self._update_msg_tags, **SHOWWRN_CONFIG).pack(side='left') Checkbutton(buttons, text='Show Errors', var=self._show_errors, command=self._update_msg_tags, **SHOWERR_CONFIG).pack(side='left') self._update_msg_tags() def _update_msg_tags(self, *e): elide_errors = not self._show_errors.get() elide_warnings = not self._show_warnings.get() elide_messages = not self._show_messages.get() elide_headers = elide_errors and elide_warnings self._messages.tag_config('error', elide=elide_errors) self._messages.tag_config('guierror', elide=elide_errors) self._messages.tag_config('warning', elide=elide_warnings) self._messages.tag_config('message', elide=elide_messages) self._messages.tag_config('header', elide=elide_headers) def _init_options(self, optsframe, ctrlframe): self._leftImage=PhotoImage(master=self._root, data=LEFT_GIF) self._rightImage=PhotoImage(master=self._root, data=RIGHT_GIF) # Set up the options control frame b1 = Button(ctrlframe, text="Options", justify='center', border=0, relief='flat', command=self._options_toggle, padx=2, underline=0, pady=0, highlightthickness=0, activebackground=BG_COLOR, **COLOR_CONFIG) b2 = Button(ctrlframe, image=self._rightImage, relief='flat', border=0, command=self._options_toggle, activebackground=BG_COLOR, **COLOR_CONFIG) self._option_button = b2 self._options_visible = 0 b2.pack(side="right") b1.pack(side="right") oframe2 = Frame(optsframe, relief='groove', border=2, background=BG_COLOR) oframe2.pack(side="right", fill='both', expand=0, padx=4, pady=3, ipadx=4) Label(oframe2, text="Project Options", font='helvetica -16', **COLOR_CONFIG).pack(anchor='w') oframe3 = Frame(oframe2, background=BG_COLOR) oframe3.pack(fill='x') oframe4 = Frame(oframe2, background=BG_COLOR) oframe4.pack(fill='x') oframe7 = Frame(oframe2, background=BG_COLOR) oframe7.pack(fill='x') div = Frame(oframe2, background=BG_COLOR, border=1, relief='sunk') div.pack(ipady=1, fill='x', padx=4, pady=2) Label(oframe2, text="Help File", font='helvetica -16', **COLOR_CONFIG).pack(anchor='w') oframe5 = Frame(oframe2, background=BG_COLOR) oframe5.pack(fill='x') div = Frame(oframe2, background=BG_COLOR, border=1, relief='sunk') div.pack(ipady=1, fill='x', padx=4, pady=2) Label(oframe2, text="CSS Stylesheet", font='helvetica -16', **COLOR_CONFIG).pack(anchor='w') oframe6 = Frame(oframe2, background=BG_COLOR) oframe6.pack(fill='x') #==================== oframe3 ==================== # -n NAME, --name NAME row = 0 l = Label(oframe3, text="Project Name:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') self._name_entry = Entry(oframe3, **ENTRY_CONFIG) self._name_entry.grid(row=row, column=1, sticky='ew', columnspan=3) # -u URL, --url URL row += 1 l = Label(oframe3, text="Project URL:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') self._url_entry = Entry(oframe3, **ENTRY_CONFIG) self._url_entry.grid(row=row, column=1, sticky='ew', columnspan=3) # -o DIR, --output DIR row += 1 l = Label(oframe3, text="Output Directory:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') self._out_entry = Entry(oframe3, **ENTRY_CONFIG) self._out_entry.grid(row=row, column=1, sticky='ew', columnspan=2) self._out_browse = Button(oframe3, text="Browse", command=self._browse_out, **BUTTON_CONFIG) self._out_browse.grid(row=row, column=3, sticky='ew', padx=2) #==================== oframe4 ==================== # --no-frames row = 0 self._frames_var = IntVar(self._root) self._frames_var.set(1) l = Label(oframe4, text="Generate a frame-based table of contents", **COLOR_CONFIG) l.grid(row=row, column=1, sticky='w') cb = Checkbutton(oframe4, var=self._frames_var, **CBUTTON_CONFIG) cb.grid(row=row, column=0, sticky='e') # --no-private row += 1 self._private_var = IntVar(self._root) self._private_var.set(1) l = Label(oframe4, text="Generate documentation for private objects", **COLOR_CONFIG) l.grid(row=row, column=1, sticky='w') cb = Checkbutton(oframe4, var=self._private_var, **CBUTTON_CONFIG) cb.grid(row=row, column=0, sticky='e') # --show-imports row += 1 self._imports_var = IntVar(self._root) self._imports_var.set(0) l = Label(oframe4, text="List imported classes and functions", **COLOR_CONFIG) l.grid(row=row, column=1, sticky='w') cb = Checkbutton(oframe4, var=self._imports_var, **CBUTTON_CONFIG) cb.grid(row=row, column=0, sticky='e') #==================== oframe7 ==================== # --docformat row += 1 l = Label(oframe7, text="Default Docformat:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') df_var = self._docformat_var = StringVar(self._root) self._docformat_var.set('epytext') b = Radiobutton(oframe7, var=df_var, text='Epytext', value='epytext', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') b = Radiobutton(oframe7, var=df_var, text='ReStructuredText', value='restructuredtext', **CBUTTON_CONFIG) b.grid(row=row, column=2, columnspan=2, sticky='w') row += 1 b = Radiobutton(oframe7, var=df_var, text='Plaintext', value='plaintext', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') b = Radiobutton(oframe7, var=df_var, text='Javadoc', value='javadoc', **CBUTTON_CONFIG) b.grid(row=row, column=2, columnspan=2, sticky='w') row += 1 # Separater Frame(oframe7, background=BG_COLOR).grid(row=row, column=1, pady=3) row += 1 # --inheritance l = Label(oframe7, text="Inheritance Style:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') inh_var = self._inheritance_var = StringVar(self._root) self._inheritance_var.set('grouped') b = Radiobutton(oframe7, var=inh_var, text='Grouped', value='grouped', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') b = Radiobutton(oframe7, var=inh_var, text='Listed', value='listed', **CBUTTON_CONFIG) b.grid(row=row, column=2, sticky='w') b = Radiobutton(oframe7, var=inh_var, text='Included', value='included', **CBUTTON_CONFIG) b.grid(row=row, column=3, sticky='w') row += 1 # Separater Frame(oframe7, background=BG_COLOR).grid(row=row, column=1, pady=3) row += 1 # --parse-only, --introspect-only l = Label(oframe7, text="Get docs from:", **COLOR_CONFIG) l.grid(row=row, column=0, sticky='e') iop_var = self._introspect_or_parse_var = StringVar(self._root) self._introspect_or_parse_var.set('both') b = Radiobutton(oframe7, var=iop_var, text='Parsing', value='parse', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') b = Radiobutton(oframe7, var=iop_var, text='Introspecting', value='introspect', **CBUTTON_CONFIG) b.grid(row=row, column=2, sticky='w') b = Radiobutton(oframe7, var=iop_var, text='Both', value='both', **CBUTTON_CONFIG) b.grid(row=row, column=3, sticky='w') row += 1 #==================== oframe5 ==================== # --help-file FILE row = 0 self._help_var = StringVar(self._root) self._help_var.set('default') b = Radiobutton(oframe5, var=self._help_var, text='Default', value='default', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') row += 1 b = Radiobutton(oframe5, var=self._help_var, text='Select File', value='-other-', **CBUTTON_CONFIG) b.grid(row=row, column=1, sticky='w') self._help_entry = Entry(oframe5, **ENTRY_CONFIG) self._help_entry.grid(row=row, column=2, sticky='ew') self._help_browse = Button(oframe5, text='Browse', command=self._browse_help, **BUTTON_CONFIG) self._help_browse.grid(row=row, column=3, sticky='ew', padx=2) from epydoc.docwriter.html_css import STYLESHEETS items = STYLESHEETS.items() def _css_sort(css1, css2): if css1[0] == 'default': return -1 elif css2[0] == 'default': return 1 else: return cmp(css1[0], css2[0]) items.sort(_css_sort) #==================== oframe6 ==================== # -c CSS, --css CSS # --private-css CSS row = 0 #l = Label(oframe6, text="Public", **COLOR_CONFIG) #l.grid(row=row, column=0, sticky='e') #l = Label(oframe6, text="Private", **COLOR_CONFIG) #l.grid(row=row, column=1, sticky='w') row += 1 css_var = self._css_var = StringVar(self._root) css_var.set('default') #private_css_var = self._private_css_var = StringVar(self._root) #private_css_var.set('default') for (name, (sheet, descr)) in items: b = Radiobutton(oframe6, var=css_var, value=name, **CBUTTON_CONFIG) b.grid(row=row, column=0, sticky='e') #b = Radiobutton(oframe6, var=private_css_var, value=name, # text=name, **CBUTTON_CONFIG) #b.grid(row=row, column=1, sticky='w') l = Label(oframe6, text=descr, **COLOR_CONFIG) l.grid(row=row, column=1, sticky='w') row += 1 b = Radiobutton(oframe6, var=css_var, value='-other-', **CBUTTON_CONFIG) b.grid(row=row, column=0, sticky='e') #b = Radiobutton(oframe6, text='Select File', var=private_css_var, # value='-other-', **CBUTTON_CONFIG) #b.grid(row=row, column=1, sticky='w') #l = Label(oframe6, text='Select File', **COLOR_CONFIG) #l.grid(row=row, column=1, sticky='w') self._css_entry = Entry(oframe6, **ENTRY_CONFIG) self._css_entry.grid(row=row, column=1, sticky='ew') self._css_browse = Button(oframe6, text="Browse", command=self._browse_css, **BUTTON_CONFIG) self._css_browse.grid(row=row, column=2, sticky='ew', padx=2) def _init_bindings(self): self._root.bind('', self._delete_module) self._root.bind('', self._options_toggle) self._root.bind('', self._messages_toggle) self._root.bind('', self._go) self._root.bind('', self._go) self._root.bind('', self._new) self._root.bind('', self._open) self._root.bind('', self._save) self._root.bind('', self._saveas) def _options_toggle(self, *e): if self._options_visible: self._optsframe.forget() self._option_button['image'] = self._rightImage self._options_visible = 0 else: self._optsframe.pack(fill='both', side='right') self._option_button['image'] = self._leftImage self._options_visible = 1 def _messages_toggle(self, *e): if self._messages_visible: self._msgsframe.forget() self._message_button['image'] = self._rightImage self._messages_visible = 0 else: self._msgsframe.pack(fill='both', side='bottom', expand=1) self._message_button['image'] = self._leftImage self._messages_visible = 1 def _configure(self, event): self._W = event.width-DW def _delete_module(self, *e): selection = self._module_list.curselection() if len(selection) != 1: return self._module_list.delete(selection[0]) def _entry_module(self, *e): modules = [self._module_entry.get()] if glob.has_magic(modules[0]): modules = glob.glob(modules[0]) for name in modules: self.add_module(name, check=1) self._module_entry.delete(0, 'end') def _browse_module(self, *e): title = 'Select a module for documentation' ftypes = [('Python module', '.py'), ('Python extension', '.so'), ('All files', '*')] filename = askopenfilename(filetypes=ftypes, title=title, defaultextension='.py', initialdir=self._init_dir) if not filename: return self._init_dir = os.path.dirname(filename) self.add_module(filename, check=1) def _browse_css(self, *e): title = 'Select a CSS stylesheet' ftypes = [('CSS Stylesheet', '.css'), ('All files', '*')] filename = askopenfilename(filetypes=ftypes, title=title, defaultextension='.css') if not filename: return self._css_entry.delete(0, 'end') self._css_entry.insert(0, filename) def _browse_help(self, *e): title = 'Select a help file' self._help_var.set('-other-') ftypes = [('HTML file', '.html'), ('All files', '*')] filename = askopenfilename(filetypes=ftypes, title=title, defaultextension='.html') if not filename: return self._help_entry.delete(0, 'end') self._help_entry.insert(0, filename) def _browse_out(self, *e): ftypes = [('All files', '*')] title = 'Choose the output directory' if askdirectory is not None: filename = askdirectory(mustexist=0, title=title) if not filename: return else: # Hack for Python 2.1 or earlier: filename = asksaveasfilename(filetypes=ftypes, title=title, initialfile='--this directory--') if not filename: return (f1, f2) = os.path.split(filename) if f2 == '--this directory--': filename = f1 self._out_entry.delete(0, 'end') self._out_entry.insert(0, filename) def destroy(self, *e): if self._root is None: return # Unload any modules that we've imported for m in sys.modules.keys(): if m not in self._old_modules: del sys.modules[m] self._root.destroy() self._root = None def add_module(self, name, check=0): from epydoc.util import is_package_dir, is_pyname, is_module_file from epydoc.docintrospecter import get_value_from_name from epydoc.docintrospecter import get_value_from_filename if (os.path.isfile(name) or is_package_dir(name) or is_pyname(name)): # Check that it's a good module, if requested. if check: try: if is_module_file(name) or is_package_dir(name): get_value_from_filename(name) elif os.path.isfile(name): get_value_from_scriptname(name) else: get_value_from_name(name) except ImportError, e: log.error(e) self._update_messages() self._root.bell() return # Add the module to the list of modules. self._module_list.insert('end', name) self._module_list.yview('end') else: log.error("Couldn't find %r" % name) self._update_messages() self._root.bell() def mainloop(self, *args, **kwargs): self._root.mainloop(*args, **kwargs) def _getopts(self): options = {} options['modules'] = self._module_list.get(0, 'end') options['prj_name'] = self._name_entry.get() or '' options['prj_url'] = self._url_entry.get() or None options['docformat'] = self._docformat_var.get() options['inheritance'] = self._inheritance_var.get() options['introspect_or_parse'] = self._introspect_or_parse_var.get() options['target'] = self._out_entry.get() or 'html' options['frames'] = self._frames_var.get() options['private'] = self._private_var.get() options['show_imports'] = self._imports_var.get() if self._help_var.get() == '-other-': options['help'] = self._help_entry.get() or None else: options['help'] = None if self._css_var.get() == '-other-': options['css'] = self._css_entry.get() or 'default' else: options['css'] = self._css_var.get() or 'default' #if self._private_css_var.get() == '-other-': # options['private_css'] = self._css_entry.get() or 'default' #else: # options['private_css'] = self._private_css_var.get() or 'default' return options def _go(self, *e): if len(self._module_list.get(0,'end')) == 0: self._root.bell() return if self._progress[0] != None: self._cancel[0] = 1 return # Construct the argument list for document(). opts = self._getopts() self._progress[0] = 0.0 self._cancel[0] = 0 args = (opts, self._cancel, self._progress) # Clear the messages window. self._messages['state'] = 'normal' self._messages.delete('0.0', 'end') self._messages['state'] = 'disabled' self._logger.clear() # Restore the module list. This will force re-loading of # anything that we're documenting. for m in sys.modules.keys(): if m not in self._old_modules: del sys.modules[m] # [xx] Reset caches?? # Start documenting start_new_thread(document, args) # Start the progress bar. self._go_button['text'] = 'Stop' self._afterid += 1 dt = 300 # How often to update, in milliseconds self._update(dt, self._afterid) def _update_messages(self): while 1: level, data = self._logger.read() if data is None: break self._messages['state'] = 'normal' if level == 'header': self._messages.insert('end', data, 'header') elif level == 'uline': self._messages.insert('end', data, 'uline header') elif level >= log.ERROR: data= data.rstrip()+'\n\n' self._messages.insert('end', data, 'guierror') elif level >= log.DOCSTRING_WARNING: data= data.rstrip()+'\n\n' self._messages.insert('end', data, 'warning') elif log >= log.INFO: data= data.rstrip()+'\n\n' self._messages.insert('end', data, 'message') # if data == '\n': # if self._last_tag != 'header2': # self._messages.insert('end', '\n', self._last_tag) # elif data == '='*75: # if self._messages.get('end-3c', 'end') == '\n\n\n': # self._messages.delete('end-1c') # self._in_header = 1 # self._messages.insert('end', ' '*75, 'uline header') # self._last_tag = 'header' # elif data == '-'*75: # self._in_header = 0 # self._last_tag = 'header2' # elif self._in_header: # self._messages.insert('end', data, 'header') # self._last_tag = 'header' # elif re.match(r'\s*(L\d+:|-)?\s*Warning: ', data): # self._messages.insert('end', data, 'warning') # self._last_tag = 'warning' # else: # self._messages.insert('end', data, 'error') # self._last_tag = 'error' self._messages['state'] = 'disabled' self._messages.yview('end') def _update(self, dt, id): if self._root is None: return if self._progress[0] is None: return if id != self._afterid: return # Update the messages box self._update_messages() # Update the progress bar. if self._progress[0] == 'done': p = self._W + DX elif self._progress[0] == 'cancel': p = -5 else: p = DX + self._W * self._progress[0] self._canvas.coords(self._r1, DX+1, DY+1, p, self._H+1) self._canvas.coords(self._r2, DX, DY, p-1, self._H) self._canvas.coords(self._r3, DX+1, DY+1, p, self._H+1) # Are we done? if self._progress[0] in ('done', 'cancel'): if self._progress[0] == 'cancel': self._root.bell() self._go_button['text'] = 'Start' self._progress[0] = None return self._root.after(dt, self._update, dt, id) def _new(self, *e): self._module_list.delete(0, 'end') self._name_entry.delete(0, 'end') self._url_entry.delete(0, 'end') self._docformat_var.set('epytext') self._inheritance_var.set('grouped') self._introspect_or_parse_var.set('both') self._out_entry.delete(0, 'end') self._module_entry.delete(0, 'end') self._css_entry.delete(0, 'end') self._help_entry.delete(0, 'end') self._frames_var.set(1) self._private_var.set(1) self._imports_var.set(0) self._css_var.set('default') #self._private_css_var.set('default') self._help_var.set('default') self._filename = None self._init_dir = None def _open(self, *e): title = 'Open project' ftypes = [('Project file', '.prj'), ('All files', '*')] filename = askopenfilename(filetypes=ftypes, title=title, defaultextension='.css') if not filename: return self.open(filename) def open(self, prjfile): from epydoc.docwriter.html_css import STYLESHEETS self._filename = prjfile try: opts = load(open(prjfile, 'r')) modnames = list(opts.get('modules', [])) modnames.sort() self._module_list.delete(0, 'end') for name in modnames: self.add_module(name) self._module_entry.delete(0, 'end') self._name_entry.delete(0, 'end') if opts.get('prj_name'): self._name_entry.insert(0, opts['prj_name']) self._url_entry.delete(0, 'end') if opts.get('prj_url'): self._url_entry.insert(0, opts['prj_url']) self._docformat_var.set(opts.get('docformat', 'epytext')) self._inheritance_var.set(opts.get('inheritance', 'grouped')) self._introspect_or_parse_var.set( opts.get('introspect_or_parse', 'both')) self._help_entry.delete(0, 'end') if opts.get('help') is None: self._help_var.set('default') else: self._help_var.set('-other-') self._help_entry.insert(0, opts.get('help')) self._out_entry.delete(0, 'end') self._out_entry.insert(0, opts.get('target', 'html')) self._frames_var.set(opts.get('frames', 1)) self._private_var.set(opts.get('private', 1)) self._imports_var.set(opts.get('show_imports', 0)) self._css_entry.delete(0, 'end') if opts.get('css', 'default') in STYLESHEETS.keys(): self._css_var.set(opts.get('css', 'default')) else: self._css_var.set('-other-') self._css_entry.insert(0, opts.get('css', 'default')) #if opts.get('private_css', 'default') in STYLESHEETS.keys(): # self._private_css_var.set(opts.get('private_css', 'default')) #else: # self._private_css_var.set('-other-') # self._css_entry.insert(0, opts.get('private_css', 'default')) except Exception, e: log.error('Error opening %s: %s' % (prjfile, e)) self._root.bell() def _save(self, *e): if self._filename is None: return self._saveas() try: opts = self._getopts() dump(opts, open(self._filename, 'w')) except Exception, e: if self._filename is None: log.error('Error saving: %s' % e) else: log.error('Error saving %s: %s' % (self._filename, e)) self._root.bell() def _saveas(self, *e): title = 'Save project as' ftypes = [('Project file', '.prj'), ('All files', '*')] filename = asksaveasfilename(filetypes=ftypes, title=title, defaultextension='.prj') if not filename: return self._filename = filename self._save() def _version(): """ Display the version information, and exit. @rtype: C{None} """ import epydoc print "Epydoc version %s" % epydoc.__version__ sys.exit(0) # At some point I could add: # --show-messages, --hide-messages # --show-options, --hide-options def _usage(): print print 'Usage: epydocgui [OPTIONS] [FILE.prj | MODULES...]' print print ' FILE.prj An epydoc GUI project file.' print ' MODULES... A list of Python modules to document.' print ' -V, --version Print the version of epydoc.' print ' -h, -?, --help, --usage Display this usage message' print ' --debug Do not suppress error messages' print sys.exit(0) def _error(s): s = '%s; run "%s -h" for usage' % (s, os.path.basename(sys.argv[0])) if len(s) > 80: i = s.rfind(' ', 0, 80) if i>0: s = s[:i]+'\n'+s[i+1:] print >>sys.stderr, s sys.exit(1) def gui(): global DEBUG sys.stderr = sys.__stderr__ projects = [] modules = [] for arg in sys.argv[1:]: if arg[0] == '-': if arg != '-V': arg = arg.lower() if arg in ('-h', '--help', '-?', '--usage'): _usage() elif arg in ('-V', '--version'): _version() elif arg in ('--debug',): DEBUG = 1 else: _error('Unknown parameter %r' % arg) elif arg[-4:] == '.prj': projects.append(arg) else: modules.append(arg) if len(projects) > 1: _error('Too many projects') if len(projects) == 1: if len(modules) > 0: _error('You must specify either a project or a list of modules') if not os.path.exists(projects[0]): _error('Cannot open project file %s' % projects[0]) gui = EpydocGUI() gui.open(projects[0]) gui.mainloop() else: gui = EpydocGUI() for module in modules: gui.add_module(module, check=1) gui.mainloop() if __name__ == '__main__': gui() epydoc-3.0.1+dfsg/epydoc/docintrospecter.py0000644000175000017500000012037310747624123021255 0ustar pronovicpronovic# epydoc -- Introspection # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: docintrospecter.py 1678 2008-01-29 17:21:29Z edloper $ """ Extract API documentation about python objects by directly introspecting their values. The function L{introspect_docs()}, which provides the main interface of this module, examines a Python objects via introspection, and uses the information it finds to create an L{APIDoc} objects containing the API documentation for that objects. The L{register_introspecter()} method can be used to extend the functionality of C{docintrospector}, by providing methods that handle special value types. """ __docformat__ = 'epytext en' ###################################################################### ## Imports ###################################################################### import inspect, re, sys, os.path, imp # API documentation encoding: from epydoc.apidoc import * # Type comparisons: from types import * # Error reporting: from epydoc import log # Helper functions: from epydoc.util import * # For extracting encoding for docstrings: import epydoc.docparser # Builtin values import __builtin__ # Backwards compatibility from epydoc.compat import * ###################################################################### ## Caches ###################################################################### _valuedoc_cache = {} """A cache containing the API documentation for values that we've already seen. This cache is implemented as a dictionary that maps a value's pyid to its L{ValueDoc}. Note that if we encounter a value but decide not to introspect it (because it's imported from another module), then C{_valuedoc_cache} will contain an entry for the value, but the value will not be listed in L{_introspected_values}.""" _introspected_values = {} """A record which values we've introspected, encoded as a dictionary from pyid to C{bool}.""" def clear_cache(): """ Discard any cached C{APIDoc} values that have been computed for introspected values. """ _valuedoc_cache.clear() _introspected_values.clear() ###################################################################### ## Introspection ###################################################################### def introspect_docs(value=None, name=None, filename=None, context=None, is_script=False, module_name=None): """ Generate the API documentation for a specified object by introspecting Python values, and return it as a L{ValueDoc}. The object to generate documentation for may be specified using the C{value} parameter, the C{filename} parameter, I{or} the C{name} parameter. (It is an error to specify more than one of these three parameters, or to not specify any of them.) @param value: The python object that should be documented. @param filename: The name of the file that contains the python source code for a package, module, or script. If C{filename} is specified, then C{introspect} will return a C{ModuleDoc} describing its contents. @param name: The fully-qualified python dotted name of any value (including packages, modules, classes, and functions). C{DocParser} will automatically figure out which module(s) it needs to import in order to find the documentation for the specified object. @param context: The API documentation for the class of module that contains C{value} (if available). @param module_name: The name of the module where the value is defined. Useful to retrieve the docstring encoding if there is no way to detect the module by introspection (such as in properties) """ if value is None and name is not None and filename is None: value = get_value_from_name(DottedName(name)) elif value is None and name is None and filename is not None: if is_script: value = get_value_from_scriptname(filename) else: value = get_value_from_filename(filename, context) elif name is None and filename is None: # it's ok if value is None -- that's a value, after all. pass else: raise ValueError("Expected exactly one of the following " "arguments: value, name, filename") pyid = id(value) # If we've already introspected this value, then simply return # its ValueDoc from our cache. if pyid in _introspected_values: # If the file is a script, then adjust its name. if is_script and filename is not None: _valuedoc_cache[pyid].canonical_name = DottedName( munge_script_name(str(filename))) return _valuedoc_cache[pyid] # Create an initial value doc for this value & add it to the cache. val_doc = _get_valuedoc(value) # Introspect the value. _introspected_values[pyid] = True introspect_func = _get_introspecter(value) introspect_func(value, val_doc, module_name=module_name) # Set canonical name, if it was given if val_doc.canonical_name is UNKNOWN and name is not None: val_doc.canonical_name = DottedName(name) # If the file is a script, then adjust its name. if is_script and filename is not None: val_doc.canonical_name = DottedName(munge_script_name(str(filename))) if val_doc.canonical_name is UNKNOWN and filename is not None: shadowed_name = DottedName(value.__name__) log.warning("Module %s is shadowed by a variable with " "the same name." % shadowed_name) val_doc.canonical_name = DottedName(str(shadowed_name)+"'") return val_doc def _get_valuedoc(value): """ If a C{ValueDoc} for the given value exists in the valuedoc cache, then return it; otherwise, create a new C{ValueDoc}, add it to the cache, and return it. When possible, the new C{ValueDoc}'s C{pyval}, C{repr}, and C{canonical_name} attributes will be set appropriately. """ pyid = id(value) val_doc = _valuedoc_cache.get(pyid) if val_doc is None: try: canonical_name = get_canonical_name(value, strict=True) except DottedName.InvalidDottedName: canonical_name = UNKNOWN val_doc = ValueDoc(pyval=value, canonical_name = canonical_name, docs_extracted_by='introspecter') _valuedoc_cache[pyid] = val_doc # If it's a module, then do some preliminary introspection. # Otherwise, check what the containing module is (used e.g. # to decide what markup language should be used for docstrings) if inspect.ismodule(value): introspect_module(value, val_doc, preliminary=True) val_doc.defining_module = val_doc else: module_name = str(get_containing_module(value)) module = sys.modules.get(module_name) if module is not None and inspect.ismodule(module): val_doc.defining_module = _get_valuedoc(module) return val_doc #//////////////////////////////////////////////////////////// # Module Introspection #//////////////////////////////////////////////////////////// #: A list of module variables that should not be included in a #: module's API documentation. UNDOCUMENTED_MODULE_VARS = ( '__builtins__', '__doc__', '__all__', '__file__', '__path__', '__name__', '__extra_epydoc_fields__', '__docformat__') def introspect_module(module, module_doc, module_name=None, preliminary=False): """ Add API documentation information about the module C{module} to C{module_doc}. """ module_doc.specialize_to(ModuleDoc) # Record the module's docformat if hasattr(module, '__docformat__'): module_doc.docformat = unicode(module.__docformat__) # Record the module's filename if hasattr(module, '__file__'): try: module_doc.filename = unicode(module.__file__) except KeyboardInterrupt: raise except: pass if module_doc.filename is not UNKNOWN: try: module_doc.filename = py_src_filename(module_doc.filename) except ValueError: pass # If this is just a preliminary introspection, then don't do # anything else. (Typically this is true if this module was # imported, but is not included in the set of modules we're # documenting.) module_doc.variables = {} if preliminary: return # Record the module's docstring if hasattr(module, '__doc__'): module_doc.docstring = get_docstring(module) # If the module has a __path__, then it's (probably) a # package; so set is_package=True and record its __path__. if hasattr(module, '__path__'): module_doc.is_package = True try: module_doc.path = [unicode(p) for p in module.__path__] except KeyboardInterrupt: raise except: pass else: module_doc.is_package = False # Make sure we have a name for the package. dotted_name = module_doc.canonical_name if dotted_name is UNKNOWN: dotted_name = DottedName(module.__name__) name_without_primes = DottedName(str(dotted_name).replace("'", "")) # Record the module's parent package, if it has one. if len(dotted_name) > 1: package_name = str(dotted_name.container()) package = sys.modules.get(package_name) if package is not None: module_doc.package = introspect_docs(package) else: module_doc.package = None # Initialize the submodules property module_doc.submodules = [] # Add the module to its parent package's submodules list. if module_doc.package not in (None, UNKNOWN): module_doc.package.submodules.append(module_doc) # Look up the module's __all__ attribute (public names). public_names = None if hasattr(module, '__all__'): try: public_names = set([str(name) for name in module.__all__]) except KeyboardInterrupt: raise except: pass # Record the module's variables. module_doc.variables = {} for child_name in dir(module): if child_name in UNDOCUMENTED_MODULE_VARS: continue child = getattr(module, child_name) # Create a VariableDoc for the child, and introspect its # value if it's defined in this module. container = get_containing_module(child) if ((container is not None and container == name_without_primes) or (public_names is not None and child_name in public_names)): # Local variable. child_val_doc = introspect_docs(child, context=module_doc, module_name=dotted_name) child_var_doc = VariableDoc(name=child_name, value=child_val_doc, is_imported=False, container=module_doc, docs_extracted_by='introspecter') elif container is None or module_doc.canonical_name is UNKNOWN: # Don't introspect stuff "from __future__" if is_future_feature(child): continue # Possibly imported variable. child_val_doc = introspect_docs(child, context=module_doc) child_var_doc = VariableDoc(name=child_name, value=child_val_doc, container=module_doc, docs_extracted_by='introspecter') else: # Imported variable. child_val_doc = _get_valuedoc(child) child_var_doc = VariableDoc(name=child_name, value=child_val_doc, is_imported=True, container=module_doc, docs_extracted_by='introspecter') # If the module's __all__ attribute is set, use it to set the # variables public/private status and imported status. if public_names is not None: if child_name in public_names: child_var_doc.is_public = True if not isinstance(child_var_doc, ModuleDoc): child_var_doc.is_imported = False else: child_var_doc.is_public = False module_doc.variables[child_name] = child_var_doc return module_doc #//////////////////////////////////////////////////////////// # Class Introspection #//////////////////////////////////////////////////////////// #: A list of class variables that should not be included in a #: class's API documentation. UNDOCUMENTED_CLASS_VARS = ( '__doc__', '__module__', '__dict__', '__weakref__', '__slots__', '__pyx_vtable__') def introspect_class(cls, class_doc, module_name=None): """ Add API documentation information about the class C{cls} to C{class_doc}. """ class_doc.specialize_to(ClassDoc) # Record the class's docstring. class_doc.docstring = get_docstring(cls) # Record the class's __all__ attribute (public names). public_names = None if hasattr(cls, '__all__'): try: public_names = set([str(name) for name in cls.__all__]) except KeyboardInterrupt: raise except: pass # Start a list of subclasses. class_doc.subclasses = [] # Sometimes users will define a __metaclass__ that copies all # class attributes from bases directly into the derived class's # __dict__ when the class is created. (This saves the lookup time # needed to search the base tree for an attribute.) But for the # docs, we only want to list these copied attributes in the # parent. So only add an attribute if it is not identical to an # attribute of a base class. (Unfortunately, this can sometimes # cause an attribute to look like it was inherited, even though it # wasn't, if it happens to have the exact same value as the # corresponding base's attribute.) An example of a case where # this helps is PyQt -- subclasses of QWidget get about 300 # methods injected into them. base_children = {} # Record the class's base classes; and add the class to its # base class's subclass lists. if hasattr(cls, '__bases__'): try: bases = list(cls.__bases__) except: bases = None log.warning("Class '%s' defines __bases__, but it does not " "contain an iterable; ignoring base list." % getattr(cls, '__name__', '??')) if bases is not None: class_doc.bases = [] for base in bases: basedoc = introspect_docs(base) class_doc.bases.append(basedoc) basedoc.subclasses.append(class_doc) bases.reverse() for base in bases: if hasattr(base, '__dict__'): base_children.update(base.__dict__) # The module name is not defined if the class is being introspected # as another class base. if module_name is None and class_doc.defining_module not in (None, UNKNOWN): module_name = class_doc.defining_module.canonical_name # Record the class's local variables. class_doc.variables = {} if hasattr(cls, '__dict__'): private_prefix = '_%s__' % getattr(cls, '__name__', '') for child_name, child in cls.__dict__.items(): if (child_name in base_children and base_children[child_name] == child): continue if child_name.startswith(private_prefix): child_name = child_name[len(private_prefix)-2:] if child_name in UNDOCUMENTED_CLASS_VARS: continue val_doc = introspect_docs(child, context=class_doc, module_name=module_name) var_doc = VariableDoc(name=child_name, value=val_doc, container=class_doc, docs_extracted_by='introspecter') if public_names is not None: var_doc.is_public = (child_name in public_names) class_doc.variables[child_name] = var_doc return class_doc #//////////////////////////////////////////////////////////// # Routine Introspection #//////////////////////////////////////////////////////////// def introspect_routine(routine, routine_doc, module_name=None): """Add API documentation information about the function C{routine} to C{routine_doc} (specializing it to C{Routine_doc}).""" routine_doc.specialize_to(RoutineDoc) # Extract the underying function if isinstance(routine, MethodType): func = routine.im_func elif isinstance(routine, staticmethod): func = routine.__get__(0) elif isinstance(routine, classmethod): func = routine.__get__(0).im_func else: func = routine # Record the function's docstring. routine_doc.docstring = get_docstring(func) # Record the function's signature. if isinstance(func, FunctionType): (args, vararg, kwarg, defaults) = inspect.getargspec(func) # Add the arguments. routine_doc.posargs = args routine_doc.vararg = vararg routine_doc.kwarg = kwarg # Set default values for positional arguments. routine_doc.posarg_defaults = [None]*len(args) if defaults is not None: offset = len(args)-len(defaults) for i in range(len(defaults)): default_val = introspect_docs(defaults[i]) routine_doc.posarg_defaults[i+offset] = default_val # If it's a bound method, then strip off the first argument. if isinstance(routine, MethodType) and routine.im_self is not None: routine_doc.posargs = routine_doc.posargs[1:] routine_doc.posarg_defaults = routine_doc.posarg_defaults[1:] # Set the routine's line number. if hasattr(func, 'func_code'): routine_doc.lineno = func.func_code.co_firstlineno else: # [XX] I should probably use UNKNOWN here?? # dvarrazzo: if '...' is to be changed, also check that # `docstringparser.process_arg_field()` works correctly. # See SF bug #1556024. routine_doc.posargs = ['...'] routine_doc.posarg_defaults = [None] routine_doc.kwarg = None routine_doc.vararg = None # Change type, if appropriate. if isinstance(routine, staticmethod): routine_doc.specialize_to(StaticMethodDoc) if isinstance(routine, classmethod): routine_doc.specialize_to(ClassMethodDoc) return routine_doc #//////////////////////////////////////////////////////////// # Property Introspection #//////////////////////////////////////////////////////////// def introspect_property(prop, prop_doc, module_name=None): """Add API documentation information about the property C{prop} to C{prop_doc} (specializing it to C{PropertyDoc}).""" prop_doc.specialize_to(PropertyDoc) # Record the property's docstring. prop_doc.docstring = get_docstring(prop, module_name=module_name) # Record the property's access functions. if hasattr(prop, 'fget'): prop_doc.fget = introspect_docs(prop.fget) prop_doc.fset = introspect_docs(prop.fset) prop_doc.fdel = introspect_docs(prop.fdel) return prop_doc #//////////////////////////////////////////////////////////// # Generic Value Introspection #//////////////////////////////////////////////////////////// def introspect_other(val, val_doc, module_name=None): """Specialize val_doc to a C{GenericValueDoc} and return it.""" val_doc.specialize_to(GenericValueDoc) return val_doc #//////////////////////////////////////////////////////////// # Helper functions #//////////////////////////////////////////////////////////// def isclass(object): """ Return true if the given object is a class. In particular, return true if object is an instance of C{types.TypeType} or of C{types.ClassType}. This is used instead of C{inspect.isclass()}, because the latter returns true for objects that are not classes (in particular, it returns true for any object that has a C{__bases__} attribute, including objects that define C{__getattr__} to always return a value). """ return isinstance(object, tuple(_CLASS_TYPES)) _CLASS_TYPES = set([TypeType, ClassType]) """A list of types that should be treated as classes.""" def register_class_type(typ): """Add a type to the lists of types that should be treated as classes. By default, this list contains C{TypeType} and C{ClassType}.""" _CLASS_TYPES.add(typ) __future_check_works = None def is_future_feature(object): """ Return True if C{object} results from a C{from __future__ import feature} statement. """ # Guard from unexpected implementation changes of the __future__ module. global __future_check_works if __future_check_works is not None: if __future_check_works: import __future__ return isinstance(object, __future__._Feature) else: return False else: __future_check_works = True try: return is_future_feature(object) except: __future_check_works = False log.warning("Troubles inspecting __future__. Python implementation" " may have been changed.") return False def get_docstring(value, module_name=None): """ Return the docstring for the given value; or C{None} if it does not have a docstring. @rtype: C{unicode} """ docstring = getattr(value, '__doc__', None) if docstring is None: return None elif isinstance(docstring, unicode): return docstring elif isinstance(docstring, str): try: return unicode(docstring, 'ascii') except UnicodeDecodeError: if module_name is None: module_name = get_containing_module(value) if module_name is not None: try: module = get_value_from_name(module_name) filename = py_src_filename(module.__file__) encoding = epydoc.docparser.get_module_encoding(filename) return unicode(docstring, encoding) except KeyboardInterrupt: raise except Exception: pass if hasattr(value, '__name__'): name = value.__name__ else: name = repr(value) log.warning("%s's docstring is not a unicode string, but it " "contains non-ascii data -- treating it as " "latin-1." % name) return unicode(docstring, 'latin-1') return None elif value is BuiltinMethodType: # Don't issue a warning for this special case. return None else: if hasattr(value, '__name__'): name = value.__name__ else: name = repr(value) log.warning("%s's docstring is not a string -- ignoring it." % name) return None def get_canonical_name(value, strict=False): """ @return: the canonical name for C{value}, or C{UNKNOWN} if no canonical name can be found. Currently, C{get_canonical_name} can find canonical names for: modules; functions; non-nested classes; methods of non-nested classes; and some class methods of non-nested classes. @rtype: L{DottedName} or C{UNKNOWN} """ if not hasattr(value, '__name__'): return UNKNOWN # Get the name via introspection. if isinstance(value, ModuleType): try: dotted_name = DottedName(value.__name__, strict=strict) # If the module is shadowed by a variable in its parent # package(s), then add a prime mark to the end, to # differentiate it from the variable that shadows it. if verify_name(value, dotted_name) is UNKNOWN: log.warning("Module %s is shadowed by a variable with " "the same name." % dotted_name) # Note -- this return bypasses verify_name check: return DottedName(value.__name__+"'") except DottedName.InvalidDottedName: # Name is not a valid Python identifier -- treat as script. if hasattr(value, '__file__'): filename = '%s' % value.__str__ dotted_name = DottedName(munge_script_name(filename)) elif isclass(value): if value.__module__ == '__builtin__': dotted_name = DottedName(value.__name__, strict=strict) else: dotted_name = DottedName(value.__module__, value.__name__, strict=strict) elif (inspect.ismethod(value) and value.im_self is not None and value.im_class is ClassType and not value.__name__.startswith('<')): # class method. class_name = get_canonical_name(value.im_self) if class_name is UNKNOWN: return UNKNOWN dotted_name = DottedName(class_name, value.__name__, strict=strict) elif (inspect.ismethod(value) and not value.__name__.startswith('<')): class_name = get_canonical_name(value.im_class) if class_name is UNKNOWN: return UNKNOWN dotted_name = DottedName(class_name, value.__name__, strict=strict) elif (isinstance(value, FunctionType) and not value.__name__.startswith('<')): module_name = _find_function_module(value) if module_name is None: return UNKNOWN dotted_name = DottedName(module_name, value.__name__, strict=strict) else: return UNKNOWN return verify_name(value, dotted_name) def verify_name(value, dotted_name): """ Verify the name. E.g., if it's a nested class, then we won't be able to find it with the name we constructed. """ if dotted_name is UNKNOWN: return UNKNOWN if len(dotted_name) == 1 and hasattr(__builtin__, dotted_name[0]): return dotted_name named_value = sys.modules.get(dotted_name[0]) if named_value is None: return UNKNOWN for identifier in dotted_name[1:]: try: named_value = getattr(named_value, identifier) except: return UNKNOWN if value is named_value: return dotted_name else: return UNKNOWN # [xx] not used: def value_repr(value): try: s = '%r' % value if isinstance(s, str): s = decode_with_backslashreplace(s) return s except: return UNKNOWN def get_containing_module(value): """ Return the name of the module containing the given value, or C{None} if the module name can't be determined. @rtype: L{DottedName} """ if inspect.ismodule(value): return DottedName(value.__name__) elif isclass(value): return DottedName(value.__module__) elif (inspect.ismethod(value) and value.im_self is not None and value.im_class is ClassType): # class method. return DottedName(value.im_self.__module__) elif inspect.ismethod(value): return DottedName(value.im_class.__module__) elif inspect.isroutine(value): module = _find_function_module(value) if module is None: return None return DottedName(module) else: return None def _find_function_module(func): """ @return: The module that defines the given function. @rtype: C{module} @param func: The function whose module should be found. @type func: C{function} """ if hasattr(func, '__module__'): return func.__module__ try: module = inspect.getmodule(func) if module: return module.__name__ except KeyboardInterrupt: raise except: pass # This fallback shouldn't usually be needed. But it is needed in # a couple special cases (including using epydoc to document # itself). In particular, if a module gets loaded twice, using # two different names for the same file, then this helps. for module in sys.modules.values(): if (hasattr(module, '__dict__') and hasattr(func, 'func_globals') and func.func_globals is module.__dict__): return module.__name__ return None #//////////////////////////////////////////////////////////// # Introspection Dispatch Table #//////////////////////////////////////////////////////////// _introspecter_registry = [] def register_introspecter(applicability_test, introspecter, priority=10): """ Register an introspecter function. Introspecter functions take two arguments, a python value and a C{ValueDoc} object, and should add information about the given value to the the C{ValueDoc}. Usually, the first line of an inspecter function will specialize it to a sublass of C{ValueDoc}, using L{ValueDoc.specialize_to()}: >>> def typical_introspecter(value, value_doc): ... value_doc.specialize_to(SomeSubclassOfValueDoc) ... @param priority: The priority of this introspecter, which determines the order in which introspecters are tried -- introspecters with lower numbers are tried first. The standard introspecters have priorities ranging from 20 to 30. The default priority (10) will place new introspecters before standard introspecters. """ _introspecter_registry.append( (priority, applicability_test, introspecter) ) _introspecter_registry.sort() def _get_introspecter(value): for (priority, applicability_test, introspecter) in _introspecter_registry: if applicability_test(value): return introspecter else: return introspect_other # Register the standard introspecter functions. def is_classmethod(v): return isinstance(v, classmethod) def is_staticmethod(v): return isinstance(v, staticmethod) def is_property(v): return isinstance(v, property) register_introspecter(inspect.ismodule, introspect_module, priority=20) register_introspecter(isclass, introspect_class, priority=24) register_introspecter(inspect.isroutine, introspect_routine, priority=28) register_introspecter(is_property, introspect_property, priority=30) # Register getset_descriptor as a property try: import array getset_type = type(array.array.typecode) del array def is_getset(v): return isinstance(v, getset_type) register_introspecter(is_getset, introspect_property, priority=32) except: pass # Register member_descriptor as a property try: import datetime member_type = type(datetime.timedelta.days) del datetime def is_member(v): return isinstance(v, member_type) register_introspecter(is_member, introspect_property, priority=34) except: pass #//////////////////////////////////////////////////////////// # Import support #//////////////////////////////////////////////////////////// def get_value_from_filename(filename, context=None): # Normalize the filename. filename = os.path.normpath(os.path.abspath(filename)) # Divide the filename into a base directory and a name. (For # packages, use the package's parent directory as the base, and # the directory name as its name). basedir = os.path.split(filename)[0] name = os.path.splitext(os.path.split(filename)[1])[0] if name == '__init__': basedir, name = os.path.split(basedir) name = DottedName(name) # If the context wasn't provided, then check if the file is in a # package directory. If so, then update basedir & name to contain # the topmost package's directory and the fully qualified name for # this file. (This update assume the default value of __path__ # for the parent packages; if the parent packages override their # __path__s, then this can cause us not to find the value.) if context is None: while is_package_dir(basedir): basedir, pkg_name = os.path.split(basedir) name = DottedName(pkg_name, name) # If a parent package was specified, then find the directory of # the topmost package, and the fully qualified name for this file. if context is not None: # Combine the name. name = DottedName(context.canonical_name, name) # Find the directory of the base package. while context not in (None, UNKNOWN): pkg_dir = os.path.split(context.filename)[0] basedir = os.path.split(pkg_dir)[0] context = context.package # Import the module. (basedir is the directory of the module's # topmost package, or its own directory if it's not in a package; # and name is the fully qualified dotted name for the module.) old_sys_path = sys.path[:] try: sys.path.insert(0, basedir) # This will make sure that we get the module itself, even # if it is shadowed by a variable. (E.g., curses.wrapper): _import(str(name)) if str(name) in sys.modules: return sys.modules[str(name)] else: # Use this as a fallback -- it *shouldn't* ever be needed. return get_value_from_name(name) finally: sys.path = old_sys_path def get_value_from_scriptname(filename): name = munge_script_name(filename) return _import(name, filename) def get_value_from_name(name, globs=None): """ Given a name, return the corresponding value. @param globs: A namespace to check for the value, if there is no module containing the named value. Defaults to __builtin__. """ name = DottedName(name) # Import the topmost module/package. If we fail, then check if # the requested name refers to a builtin. try: module = _import(name[0]) except ImportError, e: if globs is None: globs = __builtin__.__dict__ if name[0] in globs: try: return _lookup(globs[name[0]], name[1:]) except: raise e else: raise # Find the requested value in the module/package or its submodules. for i in range(1, len(name)): try: return _lookup(module, name[i:]) except ImportError: pass module = _import('.'.join(name[:i+1])) module = _lookup(module, name[1:i+1]) return module def _lookup(module, name): val = module for i, identifier in enumerate(name): try: val = getattr(val, identifier) except AttributeError: exc_msg = ('no variable named %s in %s' % (identifier, '.'.join(name[:1+i]))) raise ImportError(exc_msg) return val def _import(name, filename=None): """ Run the given callable in a 'sandboxed' environment. Currently, this includes saving and restoring the contents of sys and __builtins__; and suppressing stdin, stdout, and stderr. """ # Note that we just do a shallow copy of sys. In particular, # any changes made to sys.modules will be kept. But we do # explicitly store sys.path. old_sys = sys.__dict__.copy() old_sys_path = sys.path[:] old_builtins = __builtin__.__dict__.copy() # Add the current directory to sys.path, in case they're trying to # import a module by name that resides in the current directory. # But add it to the end -- otherwise, the explicit directory added # in get_value_from_filename might get overwritten sys.path.append('') # Suppress input and output. (These get restored when we restore # sys to old_sys). sys.stdin = sys.stdout = sys.stderr = _dev_null sys.__stdin__ = sys.__stdout__ = sys.__stderr__ = _dev_null # Remove any command-line arguments sys.argv = ['(imported)'] try: try: if filename is None: return __import__(name) else: # For importing scripts: return imp.load_source(name, filename) except KeyboardInterrupt: raise except: exc_typ, exc_val, exc_tb = sys.exc_info() if exc_val is None: estr = '%s' % (exc_typ,) else: estr = '%s: %s' % (exc_typ.__name__, exc_val) if exc_tb.tb_next is not None: estr += ' (line %d)' % (exc_tb.tb_next.tb_lineno,) raise ImportError(estr) finally: # Restore the important values that we saved. __builtin__.__dict__.clear() __builtin__.__dict__.update(old_builtins) sys.__dict__.clear() sys.__dict__.update(old_sys) sys.path = old_sys_path def introspect_docstring_lineno(api_doc): """ Try to determine the line number on which the given item's docstring begins. Return the line number, or C{None} if the line number can't be determined. The line number of the first line in the file is 1. """ if api_doc.docstring_lineno is not UNKNOWN: return api_doc.docstring_lineno if isinstance(api_doc, ValueDoc) and api_doc.pyval is not UNKNOWN: try: lines, lineno = inspect.findsource(api_doc.pyval) if not isinstance(api_doc, ModuleDoc): lineno += 1 for lineno in range(lineno, len(lines)): if lines[lineno].split('#', 1)[0].strip(): api_doc.docstring_lineno = lineno + 1 return lineno + 1 except IOError: pass except TypeError: pass except IndexError: log.warning('inspect.findsource(%s) raised IndexError' % api_doc.canonical_name) return None class _DevNull: """ A "file-like" object that discards anything that is written and always reports end-of-file when read. C{_DevNull} is used by L{_import()} to discard output when importing modules; and to ensure that stdin appears closed. """ def __init__(self): self.closed = 1 self.mode = 'r+' self.softspace = 0 self.name='' def close(self): pass def flush(self): pass def read(self, size=0): return '' def readline(self, size=0): return '' def readlines(self, sizehint=0): return [] def seek(self, offset, whence=0): pass def tell(self): return 0L def truncate(self, size=0): pass def write(self, str): pass def writelines(self, sequence): pass xreadlines = readlines _dev_null = _DevNull() ###################################################################### ## Zope InterfaceClass ###################################################################### try: from zope.interface.interface import InterfaceClass as _ZopeInterfaceClass register_class_type(_ZopeInterfaceClass) except: pass ###################################################################### ## Zope Extension classes ###################################################################### try: # Register type(ExtensionClass.ExtensionClass) from ExtensionClass import ExtensionClass as _ExtensionClass _ZopeType = type(_ExtensionClass) def _is_zope_type(val): return isinstance(val, _ZopeType) register_introspecter(_is_zope_type, introspect_class) # Register ExtensionClass.*MethodType from ExtensionClass import PythonMethodType as _ZopeMethodType from ExtensionClass import ExtensionMethodType as _ZopeCMethodType def _is_zope_method(val): return isinstance(val, (_ZopeMethodType, _ZopeCMethodType)) register_introspecter(_is_zope_method, introspect_routine) except: pass # [xx] 0 # hm.. otherwise the following gets treated as a docstring! ouch! """ ###################################################################### ## Zope Extension... ###################################################################### class ZopeIntrospecter(Introspecter): VALUEDOC_CLASSES = Introspecter.VALUEDOC_CLASSES.copy() VALUEDOC_CLASSES.update({ 'module': ZopeModuleDoc, 'class': ZopeClassDoc, 'interface': ZopeInterfaceDoc, 'attribute': ZopeAttributeDoc, }) def add_module_child(self, child, child_name, module_doc): if isinstance(child, zope.interfaces.Interface): module_doc.add_zope_interface(child_name) else: Introspecter.add_module_child(self, child, child_name, module_doc) def add_class_child(self, child, child_name, class_doc): if isinstance(child, zope.interfaces.Interface): class_doc.add_zope_interface(child_name) else: Introspecter.add_class_child(self, child, child_name, class_doc) def introspect_zope_interface(self, interface, interfacename): pass # etc... """ epydoc-3.0.1+dfsg/epydoc/docwriter/0002755000175000017500000000000010750103105017454 5ustar pronovicpronovicepydoc-3.0.1+dfsg/epydoc/docwriter/xlink.py0000644000175000017500000004022410654406440021166 0ustar pronovicpronovic""" A Docutils_ interpreted text role for cross-API reference support. This module allows a Docutils_ document to refer to elements defined in external API documentation. It is possible to refer to many external API from the same document. Each API documentation is assigned a new interpreted text role: using such interpreted text, an user can specify an object name inside an API documentation. The system will convert such text into an url and generate a reference to it. For example, if the API ``db`` is defined, being a database package, then a certain method may be referred as:: :db:`Connection.cursor()` To define a new API, an *index file* must be provided. This file contains a mapping from the object name to the URL part required to resolve such object. Index file ---------- Each line in the the index file describes an object. Each line contains the fully qualified name of the object and the URL at which the documentation is located. The fields are separated by a ```` character. The URL's in the file are relative from the documentation root: the system can be configured to add a prefix in front of each returned URL. Allowed names ------------- When a name is used in an API text role, it is split over any *separator*. The separators defined are '``.``', '``::``', '``->``'. All the text from the first noise char (neither a separator nor alphanumeric or '``_``') is discarded. The same algorithm is applied when the index file is read. First the sequence of name parts is looked for in the provided index file. If no matching name is found, a partial match against the trailing part of the names in the index is performed. If no object is found, or if the trailing part of the name may refer to many objects, a warning is issued and no reference is created. Configuration ------------- This module provides the class `ApiLinkReader` a replacement for the Docutils standalone reader. Such reader specifies the settings required for the API canonical roles configuration. The same command line options are exposed by Epydoc. The script ``apirst2html.py`` is a frontend for the `ApiLinkReader` reader. API Linking Options:: --external-api=NAME Define a new API document. A new interpreted text role NAME will be added. --external-api-file=NAME:FILENAME Use records in FILENAME to resolve objects in the API named NAME. --external-api-root=NAME:STRING Use STRING as prefix for the URL generated from the API NAME. .. _Docutils: http://docutils.sourceforge.net/ """ # $Id: xlink.py 1586 2007-03-14 01:53:42Z dvarrazzo $ __version__ = "$Revision: 1586 $"[11:-2] __author__ = "Daniele Varrazzo" __copyright__ = "Copyright (C) 2007 by Daniele Varrazzo" __docformat__ = 'reStructuredText en' import re import sys from optparse import OptionValueError from epydoc import log class UrlGenerator: """ Generate URL from an object name. """ class IndexAmbiguous(IndexError): """ The name looked for is ambiguous """ def get_url(self, name): """Look for a name and return the matching URL documentation. First look for a fully qualified name. If not found, try with partial name. If no url exists for the given object, return `None`. :Parameters: `name` : `str` the name to look for :return: the URL that can be used to reach the `name` documentation. `None` if no such URL exists. :rtype: `str` :Exceptions: - `IndexError`: no object found with `name` - `DocUrlGenerator.IndexAmbiguous` : more than one object found with a non-fully qualified name; notice that this is an ``IndexError`` subclass """ raise NotImplementedError def get_canonical_name(self, name): """ Convert an object name into a canonical name. the canonical name of an object is a tuple of strings containing its name fragments, splitted on any allowed separator ('``.``', '``::``', '``->``'). Noise such parenthesis to indicate a function is discarded. :Parameters: `name` : `str` an object name, such as ``os.path.prefix()`` or ``lib::foo::bar`` :return: the fully qualified name such ``('os', 'path', 'prefix')`` and ``('lib', 'foo', 'bar')`` :rtype: `tuple` of `str` """ rv = [] for m in self._SEP_RE.finditer(name): groups = m.groups() if groups[0] is not None: rv.append(groups[0]) elif groups[2] is not None: break return tuple(rv) _SEP_RE = re.compile(r"""(?x) # Tokenize the input into keyword, separator, noise ([a-zA-Z0-9_]+) | # A keyword is a alphanum word ( \. | \:\: | \-\> ) | # These are the allowed separators (.) # If it doesn't fit, it's noise. # Matching a single noise char is enough, because it # is used to break the tokenization as soon as some noise # is found. """) class VoidUrlGenerator(UrlGenerator): """ Don't actually know any url, but don't report any error. Useful if an index file is not available, but a document linking to it is to be generated, and warnings are to be avoided. Don't report any object as missing, Don't return any url anyway. """ def get_url(self, name): return None class DocUrlGenerator(UrlGenerator): """ Read a *documentation index* and generate URL's for it. """ def __init__(self): self._exact_matches = {} """ A map from an object fully qualified name to its URL. Values are both the name as tuple of fragments and as read from the records (see `load_records()`), mostly to help `_partial_names` to perform lookup for unambiguous names. """ self._partial_names= {} """ A map from partial names to the fully qualified names they may refer. The keys are the possible left sub-tuples of fully qualified names, the values are list of strings as provided by the index. If the list for a given tuple contains a single item, the partial match is not ambuguous. In this case the string can be looked up in `_exact_matches`. If the name fragment is ambiguous, a warning may be issued to the user. The items can be used to provide an informative message to the user, to help him qualifying the name in a unambiguous manner. """ self.prefix = '' """ Prefix portion for the URL's returned by `get_url()`. """ self._filename = None """ Not very important: only for logging. """ def get_url(self, name): cname = self.get_canonical_name(name) url = self._exact_matches.get(cname, None) if url is None: # go for a partial match vals = self._partial_names.get(cname) if vals is None: raise IndexError( "no object named '%s' found" % (name)) elif len(vals) == 1: url = self._exact_matches[vals[0]] else: raise self.IndexAmbiguous( "found %d objects that '%s' may refer to: %s" % (len(vals), name, ", ".join(["'%s'" % n for n in vals]))) return self.prefix + url #{ Content loading # --------------- def clear(self): """ Clear the current class content. """ self._exact_matches.clear() self._partial_names.clear() def load_index(self, f): """ Read the content of an index file. Populate the internal maps with the file content using `load_records()`. :Parameters: f : `str` or file a file name or file-like object fron which read the index. """ self._filename = str(f) if isinstance(f, basestring): f = open(f) self.load_records(self._iter_tuples(f)) def _iter_tuples(self, f): """Iterate on a file returning 2-tuples.""" for nrow, row in enumerate(f): # skip blank lines row = row.rstrip() if not row: continue rec = row.split('\t', 2) if len(rec) == 2: yield rec else: log.warning("invalid row in '%s' row %d: '%s'" % (self._filename, nrow+1, row)) def load_records(self, records): """ Read a sequence of pairs name -> url and populate the internal maps. :Parameters: records : iterable the sequence of pairs (*name*, *url*) to add to the maps. """ for name, url in records: cname = self.get_canonical_name(name) if not cname: log.warning("invalid object name in '%s': '%s'" % (self._filename, name)) continue # discard duplicates if name in self._exact_matches: continue self._exact_matches[name] = url self._exact_matches[cname] = url # Link the different ambiguous fragments to the url for i in range(1, len(cname)): self._partial_names.setdefault(cname[i:], []).append(name) #{ API register # ------------ api_register = {} """ Mapping from the API name to the `UrlGenerator` to be used. Use `register_api()` to add new generators to the register. """ def register_api(name, generator=None): """Register the API `name` into the `api_register`. A registered API will be available to the markup as the interpreted text role ``name``. If a `generator` is not provided, register a `VoidUrlGenerator` instance: in this case no warning will be issued for missing names, but no URL will be generated and all the dotted names will simply be rendered as literals. :Parameters: `name` : `str` the name of the generator to be registered `generator` : `UrlGenerator` the object to register to translate names into URLs. """ if generator is None: generator = VoidUrlGenerator() api_register[name] = generator def set_api_file(name, file): """Set an URL generator populated with data from `file`. Use `file` to populate a new `DocUrlGenerator` instance and register it as `name`. :Parameters: `name` : `str` the name of the generator to be registered `file` : `str` or file the file to parse populate the URL generator """ generator = DocUrlGenerator() generator.load_index(file) register_api(name, generator) def set_api_root(name, prefix): """Set the root for the URLs returned by a registered URL generator. :Parameters: `name` : `str` the name of the generator to be updated `prefix` : `str` the prefix for the generated URL's :Exceptions: - `IndexError`: `name` is not a registered generator """ api_register[name].prefix = prefix ###################################################################### # Below this point requires docutils. try: import docutils from docutils.parsers.rst import roles from docutils import nodes, utils from docutils.readers.standalone import Reader except ImportError: docutils = roles = nodes = utils = None class Reader: settings_spec = () def create_api_role(name, problematic): """ Create and register a new role to create links for an API documentation. Create a role called `name`, which will use the URL resolver registered as ``name`` in `api_register` to create a link for an object. :Parameters: `name` : `str` name of the role to create. `problematic` : `bool` if True, the registered role will create problematic nodes in case of failed references. If False, a warning will be raised anyway, but the output will appear as an ordinary literal. """ def resolve_api_name(n, rawtext, text, lineno, inliner, options={}, content=[]): if docutils is None: raise AssertionError('requires docutils') # node in monotype font text = utils.unescape(text) node = nodes.literal(rawtext, text, **options) # Get the resolver from the register and create an url from it. try: url = api_register[name].get_url(text) except IndexError, exc: msg = inliner.reporter.warning(str(exc), line=lineno) if problematic: prb = inliner.problematic(rawtext, text, msg) return [prb], [msg] else: return [node], [] if url is not None: node = nodes.reference(rawtext, '', node, refuri=url, **options) return [node], [] roles.register_local_role(name, resolve_api_name) #{ Command line parsing # -------------------- def split_name(value): """ Split an option in form ``NAME:VALUE`` and check if ``NAME`` exists. """ parts = value.split(':', 1) if len(parts) != 2: raise OptionValueError( "option value must be specified as NAME:VALUE; got '%s' instead" % value) name, val = parts if name not in api_register: raise OptionValueError( "the name '%s' has not been registered; use --external-api" % name) return (name, val) class ApiLinkReader(Reader): """ A Docutils standalone reader allowing external documentation links. The reader configure the url resolvers at the time `read()` is invoked the first time. """ #: The option parser configuration. settings_spec = ( 'API Linking Options', None, (( 'Define a new API document. A new interpreted text role NAME will be ' 'added.', ['--external-api'], {'metavar': 'NAME', 'action': 'append'} ), ( 'Use records in FILENAME to resolve objects in the API named NAME.', ['--external-api-file'], {'metavar': 'NAME:FILENAME', 'action': 'append'} ), ( 'Use STRING as prefix for the URL generated from the API NAME.', ['--external-api-root'], {'metavar': 'NAME:STRING', 'action': 'append'} ),)) + Reader.settings_spec def __init__(self, *args, **kwargs): if docutils is None: raise AssertionError('requires docutils') Reader.__init__(self, *args, **kwargs) def read(self, source, parser, settings): self.read_configuration(settings, problematic=True) return Reader.read(self, source, parser, settings) def read_configuration(self, settings, problematic=True): """ Read the configuration for the configured URL resolver. Register a new role for each configured API. :Parameters: `settings` the settings structure containing the options to read. `problematic` : `bool` if True, the registered role will create problematic nodes in case of failed references. If False, a warning will be raised anyway, but the output will appear as an ordinary literal. """ # Read config only once if hasattr(self, '_conf'): return ApiLinkReader._conf = True try: if settings.external_api is not None: for name in settings.external_api: register_api(name) create_api_role(name, problematic=problematic) if settings.external_api_file is not None: for name, file in map(split_name, settings.external_api_file): set_api_file(name, file) if settings.external_api_root is not None: for name, root in map(split_name, settings.external_api_root): set_api_root(name, root) except OptionValueError, exc: print >>sys.stderr, "%s: %s" % (exc.__class__.__name__, exc) sys.exit(2) read_configuration = classmethod(read_configuration) epydoc-3.0.1+dfsg/epydoc/docwriter/html_colorize.py0000644000175000017500000010463210747504562022726 0ustar pronovicpronovic# # epydoc.html: HTML colorizers # Edward Loper # # Created [10/16/02 09:49 PM] # $Id: html_colorize.py 1674 2008-01-29 06:03:36Z edloper $ # """ Functions to produce colorized HTML code for various objects. Currently, C{html_colorize} defines functions to colorize Python source code. """ __docformat__ = 'epytext en' import re, codecs from epydoc import log from epydoc.util import py_src_filename from epydoc.apidoc import * import tokenize, token, cgi, keyword try: from cStringIO import StringIO except: from StringIO import StringIO ###################################################################### ## Python source colorizer ###################################################################### """ Goals: - colorize tokens appropriately (using css) - optionally add line numbers - """ #: Javascript code for the PythonSourceColorizer PYSRC_JAVASCRIPTS = '''\ function expand(id) { var elt = document.getElementById(id+"-expanded"); if (elt) elt.style.display = "block"; var elt = document.getElementById(id+"-expanded-linenums"); if (elt) elt.style.display = "block"; var elt = document.getElementById(id+"-collapsed"); if (elt) { elt.innerHTML = ""; elt.style.display = "none"; } var elt = document.getElementById(id+"-collapsed-linenums"); if (elt) { elt.innerHTML = ""; elt.style.display = "none"; } var elt = document.getElementById(id+"-toggle"); if (elt) { elt.innerHTML = "-"; } } function collapse(id) { var elt = document.getElementById(id+"-expanded"); if (elt) elt.style.display = "none"; var elt = document.getElementById(id+"-expanded-linenums"); if (elt) elt.style.display = "none"; var elt = document.getElementById(id+"-collapsed-linenums"); if (elt) { elt.innerHTML = "
"; elt.style.display="block"; } var elt = document.getElementById(id+"-toggle"); if (elt) { elt.innerHTML = "+"; } var elt = document.getElementById(id+"-collapsed"); if (elt) { elt.style.display = "block"; var indent = elt.getAttribute("indent"); var pad = elt.getAttribute("pad"); var s = ""; for (var i=0; i...
"; elt.innerHTML = s; } } function toggle(id) { elt = document.getElementById(id+"-toggle"); if (elt.innerHTML == "-") collapse(id); else expand(id); return false; } function highlight(id) { var elt = document.getElementById(id+"-def"); if (elt) elt.className = "py-highlight-hdr"; var elt = document.getElementById(id+"-expanded"); if (elt) elt.className = "py-highlight"; var elt = document.getElementById(id+"-collapsed"); if (elt) elt.className = "py-highlight"; } function num_lines(s) { var n = 1; var pos = s.indexOf("\\n"); while ( pos > 0) { n += 1; pos = s.indexOf("\\n", pos+1); } return n; } // Collapse all blocks that mave more than `min_lines` lines. function collapse_all(min_lines) { var elts = document.getElementsByTagName("div"); for (var i=0; i 0) if (elt.id.substring(split, elt.id.length) == "-expanded") if (num_lines(elt.innerHTML) > min_lines) collapse(elt.id.substring(0, split)); } } function expandto(href) { var start = href.indexOf("#")+1; if (start != 0 && start != href.length) { if (href.substring(start, href.length) != "-") { collapse_all(4); pos = href.indexOf(".", start); while (pos != -1) { var id = href.substring(start, pos); expand(id); pos = href.indexOf(".", pos+1); } var id = href.substring(start, href.length); expand(id); highlight(id); } } } function kill_doclink(id) { var parent = document.getElementById(id); parent.removeChild(parent.childNodes.item(0)); } function auto_kill_doclink(ev) { if (!ev) var ev = window.event; if (!this.contains(ev.toElement)) { var parent = document.getElementById(this.parentID); parent.removeChild(parent.childNodes.item(0)); } } function doclink(id, name, targets_id) { var elt = document.getElementById(id); // If we already opened the box, then destroy it. // (This case should never occur, but leave it in just in case.) if (elt.childNodes.length > 1) { elt.removeChild(elt.childNodes.item(0)); } else { // The outer box: relative + inline positioning. var box1 = document.createElement("div"); box1.style.position = "relative"; box1.style.display = "inline"; box1.style.top = 0; box1.style.left = 0; // A shadow for fun var shadow = document.createElement("div"); shadow.style.position = "absolute"; shadow.style.left = "-1.3em"; shadow.style.top = "-1.3em"; shadow.style.background = "#404040"; // The inner box: absolute positioning. var box2 = document.createElement("div"); box2.style.position = "relative"; box2.style.border = "1px solid #a0a0a0"; box2.style.left = "-.2em"; box2.style.top = "-.2em"; box2.style.background = "white"; box2.style.padding = ".3em .4em .3em .4em"; box2.style.fontStyle = "normal"; box2.onmouseout=auto_kill_doclink; box2.parentID = id; // Get the targets var targets_elt = document.getElementById(targets_id); var targets = targets_elt.getAttribute("targets"); var links = ""; target_list = targets.split(","); for (var i=0; i" + target[0] + ""; } // Put it all together. elt.insertBefore(box1, elt.childNodes.item(0)); //box1.appendChild(box2); box1.appendChild(shadow); shadow.appendChild(box2); box2.innerHTML = "Which "+name+" do you want to see documentation for?" + ""; } return false; } ''' PYSRC_EXPANDTO_JAVASCRIPT = '''\ ''' class PythonSourceColorizer: """ A class that renders a python module's source code into HTML pages. These HTML pages are intended to be provided along with the API documentation for a module, in case a user wants to learn more about a particular object by examining its source code. Links are therefore generated from the API documentation to the source code pages, and from the source code pages back into the API documentation. The HTML generated by C{PythonSourceColorizer} has several notable features: - CSS styles are used to color tokens according to their type. (See L{CSS_CLASSES} for a list of the different token types that are identified). - Line numbers are included to the left of each line. - The first line of each class and function definition includes a link to the API source documentation for that object. - The first line of each class and function definition includes an anchor that can be used to link directly to that class or function. - If javascript is enabled, and the page is loaded using the anchor for a class or function (i.e., if the url ends in C{'#I{}'}), then that class or function will automatically be highlighted; and all other classes and function definition blocks will be 'collapsed'. These collapsed blocks can be expanded by clicking on them. - Unicode input is supported (including automatic detection of C{'coding:'} declarations). """ #: A look-up table that is used to determine which CSS class #: should be used to colorize a given token. The following keys #: may be used: #: - Any token name (e.g., C{'STRING'}) #: - Any operator token (e.g., C{'='} or C{'@'}). #: - C{'KEYWORD'} -- Python keywords such as C{'for'} and C{'if'} #: - C{'DEFNAME'} -- the name of a class or function at the top #: of its definition statement. #: - C{'BASECLASS'} -- names of base classes at the top of a class #: definition statement. #: - C{'PARAM'} -- function parameters #: - C{'DOCSTRING'} -- docstrings #: - C{'DECORATOR'} -- decorator names #: If no CSS class can be found for a given token, then it won't #: be marked with any CSS class. CSS_CLASSES = { 'NUMBER': 'py-number', 'STRING': 'py-string', 'COMMENT': 'py-comment', 'NAME': 'py-name', 'KEYWORD': 'py-keyword', 'DEFNAME': 'py-def-name', 'BASECLASS': 'py-base-class', 'PARAM': 'py-param', 'DOCSTRING': 'py-docstring', 'DECORATOR': 'py-decorator', 'OP': 'py-op', '@': 'py-decorator', } #: HTML code for the beginning of a collapsable function or class #: definition block. The block contains two
...
#: elements -- a collapsed version and an expanded version -- and #: only one of these elements is visible at any given time. By #: default, all definition blocks are expanded. #: #: This string should be interpolated with the following values:: #: (name, indentation, name) #: Where C{name} is the anchor name for the function or class; and #: indentation is a string of whitespace used to indent the #: ellipsis marker in the collapsed version. START_DEF_BLOCK = ( '' '
') #: HTML code for the end of a collapsable function or class #: definition block. END_DEF_BLOCK = '
' #: A regular expression used to pick out the unicode encoding for #: the source file. UNICODE_CODING_RE = re.compile(r'.*?\n?.*?coding[:=]\s*([-\w.]+)') #: A configuration constant, used to determine whether or not to add #: collapsable
elements for definition blocks. ADD_DEF_BLOCKS = True #: A configuration constant, used to determine whether or not to #: add line numbers. ADD_LINE_NUMBERS = True #: A configuration constant, used to determine whether or not to #: add tooltips for linked names. ADD_TOOLTIPS = True #: If true, then try to guess which target is appropriate for #: linked names; if false, then always open a div asking the #: user which one they want. GUESS_LINK_TARGETS = False def __init__(self, module_filename, module_name, docindex=None, url_func=None, name_to_docs=None, tab_width=8): """ Create a new HTML colorizer for the specified module. @param module_filename: The name of the file containing the module; its text will be loaded from this file. @param module_name: The dotted name of the module; this will be used to create links back into the API source documentation. """ # Get the source version, if possible. try: module_filename = py_src_filename(module_filename) except: pass #: The filename of the module we're colorizing. self.module_filename = module_filename #: The dotted name of the module we're colorizing. self.module_name = module_name #: A docindex, used to create href links from identifiers to #: the API documentation for their values. self.docindex = docindex #: A mapping from short names to lists of ValueDoc, used to #: decide which values an identifier might map to when creating #: href links from identifiers to the API docs for their values. self.name_to_docs = name_to_docs #: A function that maps APIDoc -> URL, used to create href #: links from identifiers to the API documentation for their #: values. self.url_func = url_func #: The index in C{text} of the last character of the last #: token we've processed. self.pos = 0 #: A list that maps line numbers to character offsets in #: C{text}. In particular, line C{M{i}} begins at character #: C{line_offset[i]} in C{text}. Since line numbers begin at #: 1, the first element of C{line_offsets} is C{None}. self.line_offsets = [] #: A list of C{(toktype, toktext)} for all tokens on the #: logical line that we are currently processing. Once a #: complete line of tokens has been collected in C{cur_line}, #: it is sent to L{handle_line} for processing. self.cur_line = [] #: A list of the names of the class or functions that include #: the current block. C{context} has one element for each #: level of indentation; C{context[i]} is the name of the class #: or function defined by the C{i}th level of indentation, or #: C{None} if that level of indentation doesn't correspond to a #: class or function definition. self.context = [] #: A list, corresponding one-to-one with L{self.context}, #: indicating the type of each entry. Each element of #: C{context_types} is one of: C{'func'}, C{'class'}, C{None}. self.context_types = [] #: A list of indentation strings for each of the current #: block's indents. I.e., the current total indentation can #: be found by taking C{''.join(self.indents)}. self.indents = [] #: The line number of the line we're currently processing. self.lineno = 0 #: The name of the class or function whose definition started #: on the previous logical line, or C{None} if the previous #: logical line was not a class or function definition. self.def_name = None #: The type of the class or function whose definition started #: on the previous logical line, or C{None} if the previous #: logical line was not a class or function definition. #: Can be C{'func'}, C{'class'}, C{None}. self.def_type = None #: The number of spaces to replace each tab in source code with self.tab_width = tab_width def find_line_offsets(self): """ Construct the L{line_offsets} table from C{self.text}. """ # line 0 doesn't exist; line 1 starts at char offset 0. self.line_offsets = [None, 0] # Find all newlines in `text`, and add an entry to # line_offsets for each one. pos = self.text.find('\n') while pos != -1: self.line_offsets.append(pos+1) pos = self.text.find('\n', pos+1) # Add a final entry, marking the end of the string. self.line_offsets.append(len(self.text)) def lineno_to_html(self): template = '%%%ds' % self.linenum_size n = template % self.lineno return '%s' \ % (self.lineno, n) def colorize(self): """ Return an HTML string that renders the source code for the module that was specified in the constructor. """ # Initialize all our state variables self.pos = 0 self.cur_line = [] self.context = [] self.context_types = [] self.indents = [] self.lineno = 1 self.def_name = None self.def_type = None self.has_decorators = False # Cache, used so we only need to list the target elements once # for each variable. self.doclink_targets_cache = {} # Load the module's text. self.text = open(self.module_filename).read() self.text = self.text.expandtabs(self.tab_width).rstrip()+'\n' # Construct the line_offsets table. self.find_line_offsets() num_lines = self.text.count('\n')+1 self.linenum_size = len(`num_lines+1`) # Call the tokenizer, and send tokens to our `tokeneater()` # method. If anything goes wrong, then fall-back to using # the input text as-is (with no colorization). try: output = StringIO() self.out = output.write tokenize.tokenize(StringIO(self.text).readline, self.tokeneater) html = output.getvalue() if self.has_decorators: html = self._FIX_DECORATOR_RE.sub(r'\2\1', html) except tokenize.TokenError, ex: html = self.text # Check for a unicode encoding declaration. m = self.UNICODE_CODING_RE.match(self.text) if m: coding = m.group(1) else: coding = 'iso-8859-1' # Decode the html string into unicode, and then encode it back # into ascii, replacing any non-ascii characters with xml # character references. try: html = html.decode(coding).encode('ascii', 'xmlcharrefreplace') except LookupError: coding = 'iso-8859-1' html = html.decode(coding).encode('ascii', 'xmlcharrefreplace') # Call expandto. html += PYSRC_EXPANDTO_JAVASCRIPT return html def tokeneater(self, toktype, toktext, (srow,scol), (erow,ecol), line): """ A callback function used by C{tokenize.tokenize} to handle each token in the module. C{tokeneater} collects tokens into the C{self.cur_line} list until a complete logical line has been formed; and then calls L{handle_line} to process that line. """ # If we encounter any errors, then just give up. if toktype == token.ERRORTOKEN: raise tokenize.TokenError, toktype # Did we skip anything whitespace? If so, add a pseudotoken # for it, with toktype=None. (Note -- this skipped string # might also contain continuation slashes; but I won't bother # to colorize them.) startpos = self.line_offsets[srow] + scol if startpos > self.pos: skipped = self.text[self.pos:startpos] self.cur_line.append( (None, skipped) ) # Update our position. self.pos = startpos + len(toktext) # Update our current line. self.cur_line.append( (toktype, toktext) ) # When we reach the end of a line, process it. if toktype == token.NEWLINE or toktype == token.ENDMARKER: self.handle_line(self.cur_line) self.cur_line = [] _next_uid = 0 # [xx] note -- this works with byte strings, not unicode strings! # I may change it to use unicode eventually, but when I do it # needs to be changed all at once. def handle_line(self, line): """ Render a single logical line from the module, and write the generated HTML to C{self.out}. @param line: A single logical line, encoded as a list of C{(toktype,tokttext)} pairs corresponding to the tokens in the line. """ # def_name is the name of the function or class defined by # this line; or None if no funciton or class is defined. def_name = None # def_type is the type of the function or class defined by # this line; or None if no funciton or class is defined. def_type = None # does this line start a class/func def? starting_def_block = False in_base_list = False in_param_list = False in_param_default = 0 at_module_top = (self.lineno == 1) ended_def_blocks = 0 # The html output. if self.ADD_LINE_NUMBERS: s = self.lineno_to_html() self.lineno += 1 else: s = '' s += ' ' # Loop through each token, and colorize it appropriately. for i, (toktype, toktext) in enumerate(line): if type(s) is not str: if type(s) is unicode: log.error('While colorizing %s -- got unexpected ' 'unicode string' % self.module_name) s = s.encode('ascii', 'xmlcharrefreplace') else: raise ValueError('Unexpected value for s -- %s' % type(s).__name__) # For each token, determine its css class and whether it # should link to a url. css_class = None url = None tooltip = None onclick = uid = targets = None # these 3 are used together. # Is this token the class name in a class definition? If # so, then make it a link back into the API docs. if i>=2 and line[i-2][1] == 'class': in_base_list = True css_class = self.CSS_CLASSES['DEFNAME'] def_name = toktext def_type = 'class' if 'func' not in self.context_types: cls_name = self.context_name(def_name) url = self.name2url(cls_name) s = self.mark_def(s, cls_name) starting_def_block = True # Is this token the function name in a function def? If # so, then make it a link back into the API docs. elif i>=2 and line[i-2][1] == 'def': in_param_list = True css_class = self.CSS_CLASSES['DEFNAME'] def_name = toktext def_type = 'func' if 'func' not in self.context_types: cls_name = self.context_name() func_name = self.context_name(def_name) url = self.name2url(cls_name, def_name) s = self.mark_def(s, func_name) starting_def_block = True # For each indent, update the indents list (which we use # to keep track of indentation strings) and the context # list. If this indent is the start of a class or # function def block, then self.def_name will be its name; # otherwise, it will be None. elif toktype == token.INDENT: self.indents.append(toktext) self.context.append(self.def_name) self.context_types.append(self.def_type) # When we dedent, pop the last elements off the indents # list and the context list. If the last context element # is a name, then we're ending a class or function def # block; so write an end-div tag. elif toktype == token.DEDENT: self.indents.pop() self.context_types.pop() if self.context.pop(): ended_def_blocks += 1 # If this token contains whitespace, then don't bother to # give it a css tag. elif toktype in (None, tokenize.NL, token.NEWLINE, token.ENDMARKER): css_class = None # Check if the token is a keyword. elif toktype == token.NAME and keyword.iskeyword(toktext): css_class = self.CSS_CLASSES['KEYWORD'] elif in_base_list and toktype == token.NAME: css_class = self.CSS_CLASSES['BASECLASS'] elif (in_param_list and toktype == token.NAME and not in_param_default): css_class = self.CSS_CLASSES['PARAM'] # Class/function docstring. elif (self.def_name and line[i-1][0] == token.INDENT and self.is_docstring(line, i)): css_class = self.CSS_CLASSES['DOCSTRING'] # Module docstring. elif at_module_top and self.is_docstring(line, i): css_class = self.CSS_CLASSES['DOCSTRING'] # check for decorators?? elif (toktype == token.NAME and ((i>0 and line[i-1][1]=='@') or (i>1 and line[i-1][0]==None and line[i-2][1] == '@'))): css_class = self.CSS_CLASSES['DECORATOR'] self.has_decorators = True # If it's a name, try to link it. elif toktype == token.NAME: css_class = self.CSS_CLASSES['NAME'] # If we have a variable named `toktext` in the current # context, then link to that. Note that if we're inside # a function, then that function is our context, not # the namespace that contains it. [xx] this isn't always # the right thing to do. if (self.GUESS_LINK_TARGETS and self.docindex is not None and self.url_func is not None): context = [n for n in self.context if n is not None] container = self.docindex.get_vardoc( DottedName(self.module_name, *context)) if isinstance(container, NamespaceDoc): doc = container.variables.get(toktext) if doc is not None: url = self.url_func(doc) tooltip = str(doc.canonical_name) # Otherwise, check the name_to_docs index to see what # else this name might refer to. if (url is None and self.name_to_docs is not None and self.url_func is not None): docs = self.name_to_docs.get(toktext) if docs: tooltip='\n'.join([str(d.canonical_name) for d in docs]) if len(docs) == 1 and self.GUESS_LINK_TARGETS: url = self.url_func(docs[0]) else: uid, onclick, targets = self.doclink(toktext, docs) # For all other tokens, look up the CSS class to use # based on the token's type. else: if toktype == token.OP and toktext in self.CSS_CLASSES: css_class = self.CSS_CLASSES[toktext] elif token.tok_name[toktype] in self.CSS_CLASSES: css_class = self.CSS_CLASSES[token.tok_name[toktype]] else: css_class = None # update our status.. if toktext == ':': in_base_list = False in_param_list = False if toktext == '=' and in_param_list: in_param_default = True if in_param_default: if toktext in ('(','[','{'): in_param_default += 1 if toktext in (')',']','}'): in_param_default -= 1 if toktext == ',' and in_param_default == 1: in_param_default = 0 # Write this token, with appropriate colorization. if tooltip and self.ADD_TOOLTIPS: tooltip_html = ' title="%s"' % tooltip else: tooltip_html = '' if css_class: css_class_html = ' class="%s"' % css_class else: css_class_html = '' if onclick: if targets: targets_html = ' targets="%s"' % targets else: targets_html = '' s += ('' % (uid, css_class_html, targets_html, tooltip_html, css_class_html, onclick)) elif url: if isinstance(url, unicode): url = url.encode('ascii', 'xmlcharrefreplace') s += ('' % (tooltip_html, css_class_html, url)) elif css_class_html or tooltip_html: s += '' % (tooltip_html, css_class_html) if i == len(line)-1: s += ' ' # Closes s += cgi.escape(toktext) else: try: s += self.add_line_numbers(cgi.escape(toktext), css_class) except Exception, e: print (toktext, css_class, toktext.encode('ascii')) raise if onclick: s += "" elif url: s += '' elif css_class_html or tooltip_html: s += '' if self.ADD_DEF_BLOCKS: for i in range(ended_def_blocks): self.out(self.END_DEF_BLOCK) # Strip any empty s. s = re.sub(r'', '', s) # Write the line. self.out(s) if def_name and starting_def_block: self.out('
') # Add div's if we're starting a def block. if (self.ADD_DEF_BLOCKS and def_name and starting_def_block and (line[-2][1] == ':')): indentation = (''.join(self.indents)+' ').replace(' ', '+') linenum_padding = '+'*self.linenum_size name=self.context_name(def_name) self.out(self.START_DEF_BLOCK % (name, linenum_padding, indentation, name)) self.def_name = def_name self.def_type = def_type def context_name(self, extra=None): pieces = [n for n in self.context if n is not None] if extra is not None: pieces.append(extra) return '.'.join(pieces) def doclink(self, name, docs): uid = 'link-%s' % self._next_uid self._next_uid += 1 context = [n for n in self.context if n is not None] container = DottedName(self.module_name, *context) #else: # container = None targets = ','.join(['%s=%s' % (str(self.doc_descr(d,container)), str(self.url_func(d))) for d in docs]) if targets in self.doclink_targets_cache: onclick = ("return doclink('%s', '%s', '%s');" % (uid, name, self.doclink_targets_cache[targets])) return uid, onclick, None else: self.doclink_targets_cache[targets] = uid onclick = ("return doclink('%s', '%s', '%s');" % (uid, name, uid)) return uid, onclick, targets def doc_descr(self, doc, context): name = str(doc.canonical_name) descr = '%s %s' % (self.doc_kind(doc), name) if isinstance(doc, RoutineDoc): descr += '()' return descr # [XX] copied streight from html.py; this should be consolidated, # probably into apidoc. def doc_kind(self, doc): if isinstance(doc, ModuleDoc) and doc.is_package == True: return 'Package' elif (isinstance(doc, ModuleDoc) and doc.canonical_name[0].startswith('script')): return 'Script' elif isinstance(doc, ModuleDoc): return 'Module' elif isinstance(doc, ClassDoc): return 'Class' elif isinstance(doc, ClassMethodDoc): return 'Class Method' elif isinstance(doc, StaticMethodDoc): return 'Static Method' elif isinstance(doc, RoutineDoc): if (self.docindex is not None and isinstance(self.docindex.container(doc), ClassDoc)): return 'Method' else: return 'Function' else: return 'Variable' def mark_def(self, s, name): replacement = ('
\\1' '-\\2' % (name, name, name, name)) return re.sub('(.*) (.*)\Z', replacement, s) def is_docstring(self, line, i): if line[i][0] != token.STRING: return False for toktype, toktext in line[i:]: if toktype not in (token.NEWLINE, tokenize.COMMENT, tokenize.NL, token.STRING, None): return False return True def add_line_numbers(self, s, css_class): result = '' start = 0 end = s.find('\n')+1 while end: result += s[start:end-1] if css_class: result += '' result += ' ' # py-line result += '\n' if self.ADD_LINE_NUMBERS: result += self.lineno_to_html() result += ' ' if css_class: result += '' % css_class start = end end = s.find('\n', end)+1 self.lineno += 1 result += s[start:] return result def name2url(self, class_name, func_name=None): if class_name: class_name = '%s.%s' % (self.module_name, class_name) if func_name: return '%s-class.html#%s' % (class_name, func_name) else: return '%s-class.html' % class_name else: return '%s-module.html#%s' % (self.module_name, func_name) #: A regexp used to move the
that marks the beginning of a #: function or method to just before the decorators. _FIX_DECORATOR_RE = re.compile( r'((?:^\s*\d+' r'\s*(?:.*|\s*|' r'\s*.*)\n)+)' r'(
)', re.MULTILINE) _HDR = '''\ $title$ ''' _FOOT = '' if __name__=='__main__': #s = PythonSourceColorizer('../apidoc.py', 'epydoc.apidoc').colorize() s = PythonSourceColorizer('/tmp/fo.py', 'epydoc.apidoc').colorize() #print s import codecs f = codecs.open('/home/edloper/public_html/color3.html', 'w', 'ascii', 'xmlcharrefreplace') f.write(_HDR+'
'+s+'
'+_FOOT) f.close() epydoc-3.0.1+dfsg/epydoc/docwriter/dotgraph.py0000644000175000017500000014776110747415705021676 0ustar pronovicpronovic# epydoc -- Graph generation # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: dotgraph.py 1663 2007-11-07 15:29:47Z dvarrazzo $ """ Render Graphviz directed graphs as images. Below are some examples. .. importgraph:: .. classtree:: epydoc.apidoc.APIDoc .. packagetree:: epydoc :see: `The Graphviz Homepage `__ """ __docformat__ = 'restructuredtext' import re import sys from epydoc import log from epydoc.apidoc import * from epydoc.util import * from epydoc.compat import * # Backwards compatibility # colors for graphs of APIDocs MODULE_BG = '#d8e8ff' CLASS_BG = '#d8ffe8' SELECTED_BG = '#ffd0d0' BASECLASS_BG = '#e0b0a0' SUBCLASS_BG = '#e0b0a0' ROUTINE_BG = '#e8d0b0' # maybe? INH_LINK_COLOR = '#800000' ###################################################################### #{ Dot Graphs ###################################################################### DOT_COMMAND = 'dot' """The command that should be used to spawn dot""" class DotGraph: """ A ``dot`` directed graph. The contents of the graph are constructed from the following instance variables: - `nodes`: A list of `DotGraphNode`\\s, encoding the nodes that are present in the graph. Each node is characterized a set of attributes, including an optional label. - `edges`: A list of `DotGraphEdge`\\s, encoding the edges that are present in the graph. Each edge is characterized by a set of attributes, including an optional label. - `node_defaults`: Default attributes for nodes. - `edge_defaults`: Default attributes for edges. - `body`: A string that is appended as-is in the body of the graph. This can be used to build more complex dot graphs. The `link()` method can be used to resolve crossreference links within the graph. In particular, if the 'href' attribute of any node or edge is assigned a value of the form ````, then it will be replaced by the URL of the object with that name. This applies to the `body` as well as the `nodes` and `edges`. To render the graph, use the methods `write()` and `render()`. Usually, you should call `link()` before you render the graph. """ _uids = set() """A set of all uids that that have been generated, used to ensure that each new graph has a unique uid.""" DEFAULT_NODE_DEFAULTS={'fontsize':10, 'fontname': 'Helvetica'} DEFAULT_EDGE_DEFAULTS={'fontsize':10, 'fontname': 'Helvetica'} def __init__(self, title, body='', node_defaults=None, edge_defaults=None, caption=None): """ Create a new `DotGraph`. """ self.title = title """The title of the graph.""" self.caption = caption """A caption for the graph.""" self.nodes = [] """A list of the nodes that are present in the graph. :type: ``list`` of `DotGraphNode`""" self.edges = [] """A list of the edges that are present in the graph. :type: ``list`` of `DotGraphEdge`""" self.body = body """A string that should be included as-is in the body of the graph. :type: ``str``""" self.node_defaults = node_defaults or self.DEFAULT_NODE_DEFAULTS """Default attribute values for nodes.""" self.edge_defaults = edge_defaults or self.DEFAULT_EDGE_DEFAULTS """Default attribute values for edges.""" self.uid = re.sub(r'\W', '_', title).lower() """A unique identifier for this graph. This can be used as a filename when rendering the graph. No two `DotGraph`\s will have the same uid.""" # Encode the title, if necessary. if isinstance(self.title, unicode): self.title = self.title.encode('ascii', 'xmlcharrefreplace') # Make sure the UID isn't too long. self.uid = self.uid[:30] # Make sure the UID is unique if self.uid in self._uids: n = 2 while ('%s_%s' % (self.uid, n)) in self._uids: n += 1 self.uid = '%s_%s' % (self.uid, n) self._uids.add(self.uid) def to_html(self, image_file, image_url, center=True): """ Return the HTML code that should be uesd to display this graph (including a client-side image map). :param image_url: The URL of the image file for this graph; this should be generated separately with the `write()` method. """ # If dotversion >1.8.10, then we can generate the image and # the cmapx with a single call to dot. Otherwise, we need to # run dot twice. if get_dot_version() > [1,8,10]: cmapx = self._run_dot('-Tgif', '-o%s' % image_file, '-Tcmapx') if cmapx is None: return '' # failed to render else: if not self.write(image_file): return '' # failed to render cmapx = self.render('cmapx') or '' # Decode the cmapx (dot uses utf-8) try: cmapx = cmapx.decode('utf-8') except UnicodeDecodeError: log.debug('%s: unable to decode cmapx from dot; graph will ' 'not have clickable regions' % image_file) cmapx = '' title = plaintext_to_html(self.title or '') caption = plaintext_to_html(self.caption or '') if title or caption: css_class = 'graph-with-title' else: css_class = 'graph-without-title' if len(title)+len(caption) > 80: title_align = 'left' table_width = ' width="600"' else: title_align = 'center' table_width = '' if center: s = '
' if title or caption: s += ('\n \n \n
\n' % table_width) s += (' %s\n %r\n' % (cmapx.strip(), image_url, title, self.uid, css_class)) if title or caption: s += '
\n' % title_align if title: s += '%s' % title if title and caption: s += ' -- ' if caption: s += '%s' % caption s += '\n

' if center: s += '
' return s def link(self, docstring_linker): """ Replace any href attributes whose value is ```` with the url of the object whose name is ````. """ # Link xrefs in nodes self._link_href(self.node_defaults, docstring_linker) for node in self.nodes: self._link_href(node.attribs, docstring_linker) # Link xrefs in edges self._link_href(self.edge_defaults, docstring_linker) for edge in self.nodes: self._link_href(edge.attribs, docstring_linker) # Link xrefs in body def subfunc(m): url = docstring_linker.url_for(m.group(1)) if url: return 'href="%s"%s' % (url, m.group(2)) else: return '' self.body = re.sub("href\s*=\s*['\"]?<([\w\.]+)>['\"]?\s*(,?)", subfunc, self.body) def _link_href(self, attribs, docstring_linker): """Helper for `link()`""" if 'href' in attribs: m = re.match(r'^<([\w\.]+)>$', attribs['href']) if m: url = docstring_linker.url_for(m.group(1)) if url: attribs['href'] = url else: del attribs['href'] def write(self, filename, language='gif'): """ Render the graph using the output format `language`, and write the result to `filename`. :return: True if rendering was successful. """ result = self._run_dot('-T%s' % language, '-o%s' % filename) # Decode into unicode, if necessary. if language == 'cmapx' and result is not None: result = result.decode('utf-8') return (result is not None) def render(self, language='gif'): """ Use the ``dot`` command to render this graph, using the output format `language`. Return the result as a string, or ``None`` if the rendering failed. """ return self._run_dot('-T%s' % language) def _run_dot(self, *options): try: result, err = run_subprocess((DOT_COMMAND,)+options, self.to_dotfile()) if err: log.warning("Graphviz dot warning(s):\n%s" % err) except OSError, e: log.warning("Unable to render Graphviz dot graph:\n%s" % e) #log.debug(self.to_dotfile()) return None return result def to_dotfile(self): """ Return the string contents of the dot file that should be used to render this graph. """ lines = ['digraph %s {' % self.uid, 'node [%s]' % ','.join(['%s="%s"' % (k,v) for (k,v) in self.node_defaults.items()]), 'edge [%s]' % ','.join(['%s="%s"' % (k,v) for (k,v) in self.edge_defaults.items()])] if self.body: lines.append(self.body) lines.append('/* Nodes */') for node in self.nodes: lines.append(node.to_dotfile()) lines.append('/* Edges */') for edge in self.edges: lines.append(edge.to_dotfile()) lines.append('}') # Default dot input encoding is UTF-8 return u'\n'.join(lines).encode('utf-8') class DotGraphNode: _next_id = 0 def __init__(self, label=None, html_label=None, **attribs): if label is not None and html_label is not None: raise ValueError('Use label or html_label, not both.') if label is not None: attribs['label'] = label self._html_label = html_label self._attribs = attribs self.id = self.__class__._next_id self.__class__._next_id += 1 self.port = None def __getitem__(self, attr): return self._attribs[attr] def __setitem__(self, attr, val): if attr == 'html_label': self._attribs.pop('label') self._html_label = val else: if attr == 'label': self._html_label = None self._attribs[attr] = val def to_dotfile(self): """ Return the dot commands that should be used to render this node. """ attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items() if v is not None] if self._html_label: attribs.insert(0, 'label=<%s>' % (self._html_label,)) if attribs: attribs = ' [%s]' % (','.join(attribs)) return 'node%d%s' % (self.id, attribs) class DotGraphEdge: def __init__(self, start, end, label=None, **attribs): """ :type start: `DotGraphNode` :type end: `DotGraphNode` """ assert isinstance(start, DotGraphNode) assert isinstance(end, DotGraphNode) if label is not None: attribs['label'] = label self.start = start #: :type: `DotGraphNode` self.end = end #: :type: `DotGraphNode` self._attribs = attribs def __getitem__(self, attr): return self._attribs[attr] def __setitem__(self, attr, val): self._attribs[attr] = val def to_dotfile(self): """ Return the dot commands that should be used to render this edge. """ # Set head & tail ports, if the nodes have preferred ports. attribs = self._attribs.copy() if (self.start.port is not None and 'headport' not in attribs): attribs['headport'] = self.start.port if (self.end.port is not None and 'tailport' not in attribs): attribs['tailport'] = self.end.port # Convert attribs to a string attribs = ','.join(['%s="%s"' % (k,v) for (k,v) in attribs.items() if v is not None]) if attribs: attribs = ' [%s]' % attribs # Return the dotfile edge. return 'node%d -> node%d%s' % (self.start.id, self.end.id, attribs) ###################################################################### #{ Specialized Nodes for UML Graphs ###################################################################### class DotGraphUmlClassNode(DotGraphNode): """ A specialized dot graph node used to display `ClassDoc`\s using UML notation. The node is rendered as a table with three cells: the top cell contains the class name; the middle cell contains a list of attributes; and the bottom cell contains a list of operations:: +-------------+ | ClassName | +-------------+ | x: int | | ... | +-------------+ | f(self, x) | | ... | +-------------+ `DotGraphUmlClassNode`\s may be *collapsed*, in which case they are drawn as a simple box containing the class name:: +-------------+ | ClassName | +-------------+ Attributes with types corresponding to documented classes can optionally be converted into edges, using `link_attributes()`. :todo: Add more options? - show/hide operation signature - show/hide operation signature types - show/hide operation signature return type - show/hide attribute types - use qualifiers """ def __init__(self, class_doc, linker, context, collapsed=False, bgcolor=CLASS_BG, **options): """ Create a new `DotGraphUmlClassNode` based on the class `class_doc`. :Parameters: `linker` : `markup.DocstringLinker` Used to look up URLs for classes. `context` : `APIDoc` The context in which this node will be drawn; dotted names will be contextualized to this context. `collapsed` : ``bool`` If true, then display this node as a simple box. `bgcolor` : ```str``` The background color for this node. `options` : ``dict`` A set of options used to control how the node should be displayed. :Keywords: - `show_private_vars`: If false, then private variables are filtered out of the attributes & operations lists. (Default: *False*) - `show_magic_vars`: If false, then magic variables (such as ``__init__`` and ``__add__``) are filtered out of the attributes & operations lists. (Default: *True*) - `show_inherited_vars`: If false, then inherited variables are filtered out of the attributes & operations lists. (Default: *False*) - `max_attributes`: The maximum number of attributes that should be listed in the attribute box. If the class has more than this number of attributes, some will be ellided. Ellipsis is marked with ``'...'``. - `max_operations`: The maximum number of operations that should be listed in the operation box. - `add_nodes_for_linked_attributes`: If true, then `link_attributes()` will create new a collapsed node for the types of a linked attributes if no node yet exists for that type. """ if not isinstance(class_doc, ClassDoc): raise TypeError('Expected a ClassDoc as 1st argument') self.class_doc = class_doc """The class represented by this node.""" self.linker = linker """Used to look up URLs for classes.""" self.context = context """The context in which the node will be drawn.""" self.bgcolor = bgcolor """The background color of the node.""" self.options = options """Options used to control how the node is displayed.""" self.collapsed = collapsed """If true, then draw this node as a simple box.""" self.attributes = [] """The list of VariableDocs for attributes""" self.operations = [] """The list of VariableDocs for operations""" self.qualifiers = [] """List of (key_label, port) tuples.""" self.edges = [] """List of edges used to represent this node's attributes. These should not be added to the `DotGraph`; this node will generate their dotfile code directly.""" # Initialize operations & attributes lists. show_private = options.get('show_private_vars', False) show_magic = options.get('show_magic_vars', True) show_inherited = options.get('show_inherited_vars', False) for var in class_doc.sorted_variables: name = var.canonical_name[-1] if ((not show_private and var.is_public == False) or (not show_magic and re.match('__\w+__$', name)) or (not show_inherited and var.container != class_doc)): pass elif isinstance(var.value, RoutineDoc): self.operations.append(var) else: self.attributes.append(var) # Initialize our dot node settings. tooltip = self._summary(class_doc) if tooltip: # dot chokes on a \n in the attribute... tooltip = " ".join(tooltip.split()) else: tooltip = class_doc.canonical_name DotGraphNode.__init__(self, tooltip=tooltip, width=0, height=0, shape='plaintext', href=linker.url_for(class_doc) or NOOP_URL) #///////////////////////////////////////////////////////////////// #{ Attribute Linking #///////////////////////////////////////////////////////////////// SIMPLE_TYPE_RE = re.compile( r'^([\w\.]+)$') """A regular expression that matches descriptions of simple types.""" COLLECTION_TYPE_RE = re.compile( r'^(list|set|sequence|tuple|collection) of ([\w\.]+)$') """A regular expression that matches descriptions of collection types.""" MAPPING_TYPE_RE = re.compile( r'^(dict|dictionary|map|mapping) from ([\w\.]+) to ([\w\.]+)$') """A regular expression that matches descriptions of mapping types.""" MAPPING_TO_COLLECTION_TYPE_RE = re.compile( r'^(dict|dictionary|map|mapping) from ([\w\.]+) to ' r'(list|set|sequence|tuple|collection) of ([\w\.]+)$') """A regular expression that matches descriptions of mapping types whose value type is a collection.""" OPTIONAL_TYPE_RE = re.compile( r'^(None or|optional) ([\w\.]+)$|^([\w\.]+) or None$') """A regular expression that matches descriptions of optional types.""" def link_attributes(self, nodes): """ Convert any attributes with type descriptions corresponding to documented classes to edges. The following type descriptions are currently handled: - Dotted names: Create an attribute edge to the named type, labelled with the variable name. - Collections: Create an attribute edge to the named type, labelled with the variable name, and marked with '*' at the type end of the edge. - Mappings: Create an attribute edge to the named type, labelled with the variable name, connected to the class by a qualifier box that contains the key type description. - Optional: Create an attribute edge to the named type, labelled with the variable name, and marked with '0..1' at the type end of the edge. The edges created by `link_attributes()` are handled internally by `DotGraphUmlClassNode`; they should *not* be added directly to the `DotGraph`. :param nodes: A dictionary mapping from `ClassDoc`\s to `DotGraphUmlClassNode`\s, used to look up the nodes for attribute types. If the ``add_nodes_for_linked_attributes`` option is used, then new nodes will be added to this dictionary for any types that are not already listed. These added nodes must be added to the `DotGraph`. """ # Try to convert each attribute var into a graph edge. If # _link_attribute returns true, then it succeeded, so remove # that var from our attribute list; otherwise, leave that var # in our attribute list. self.attributes = [var for var in self.attributes if not self._link_attribute(var, nodes)] def _link_attribute(self, var, nodes): """ Helper for `link_attributes()`: try to convert the attribute variable `var` into an edge, and add that edge to `self.edges`. Return ``True`` iff the variable was successfully converted to an edge (in which case, it should be removed from the attributes list). """ type_descr = self._type_descr(var) or self._type_descr(var.value) # Simple type. m = self.SIMPLE_TYPE_RE.match(type_descr) if m and self._add_attribute_edge(var, nodes, m.group(1)): return True # Collection type. m = self.COLLECTION_TYPE_RE.match(type_descr) if m and self._add_attribute_edge(var, nodes, m.group(2), headlabel='*'): return True # Optional type. m = self.OPTIONAL_TYPE_RE.match(type_descr) if m and self._add_attribute_edge(var, nodes, m.group(2) or m.group(3), headlabel='0..1'): return True # Mapping type. m = self.MAPPING_TYPE_RE.match(type_descr) if m: port = 'qualifier_%s' % var.name if self._add_attribute_edge(var, nodes, m.group(3), tailport='%s:e' % port): self.qualifiers.append( (m.group(2), port) ) return True # Mapping to collection type. m = self.MAPPING_TO_COLLECTION_TYPE_RE.match(type_descr) if m: port = 'qualifier_%s' % var.name if self._add_attribute_edge(var, nodes, m.group(4), headlabel='*', tailport='%s:e' % port): self.qualifiers.append( (m.group(2), port) ) return True # We were unable to link this attribute. return False def _add_attribute_edge(self, var, nodes, type_str, **attribs): """ Helper for `link_attributes()`: try to add an edge for the given attribute variable `var`. Return ``True`` if successful. """ # Use the type string to look up a corresponding ValueDoc. type_doc = self.linker.docindex.find(type_str, var) if not type_doc: return False # Make sure the type is a class. if not isinstance(type_doc, ClassDoc): return False # Get the type ValueDoc's node. If it doesn't have one (and # add_nodes_for_linked_attributes=True), then create it. type_node = nodes.get(type_doc) if not type_node: if self.options.get('add_nodes_for_linked_attributes', True): type_node = DotGraphUmlClassNode(type_doc, self.linker, self.context, collapsed=True) nodes[type_doc] = type_node else: return False # Add an edge from self to the target type node. # [xx] should I set constraint=false here? attribs.setdefault('headport', 'body') attribs.setdefault('tailport', 'body') url = self.linker.url_for(var) or NOOP_URL self.edges.append(DotGraphEdge(self, type_node, label=var.name, arrowhead='open', href=url, tooltip=var.canonical_name, labeldistance=1.5, **attribs)) return True #///////////////////////////////////////////////////////////////// #{ Helper Methods #///////////////////////////////////////////////////////////////// def _summary(self, api_doc): """Return a plaintext summary for `api_doc`""" if not isinstance(api_doc, APIDoc): return '' if api_doc.summary in (None, UNKNOWN): return '' summary = api_doc.summary.to_plaintext(None).strip() return plaintext_to_html(summary) _summary = classmethod(_summary) def _type_descr(self, api_doc): """Return a plaintext type description for `api_doc`""" if not hasattr(api_doc, 'type_descr'): return '' if api_doc.type_descr in (None, UNKNOWN): return '' type_descr = api_doc.type_descr.to_plaintext(self.linker).strip() return plaintext_to_html(type_descr) def _tooltip(self, var_doc): """Return a tooltip for `var_doc`.""" return (self._summary(var_doc) or self._summary(var_doc.value) or var_doc.canonical_name) #///////////////////////////////////////////////////////////////// #{ Rendering #///////////////////////////////////////////////////////////////// def _attribute_cell(self, var_doc): # Construct the label label = var_doc.name type_descr = (self._type_descr(var_doc) or self._type_descr(var_doc.value)) if type_descr: label += ': %s' % type_descr # Get the URL url = self.linker.url_for(var_doc) or NOOP_URL # Construct & return the pseudo-html code return self._ATTRIBUTE_CELL % (url, self._tooltip(var_doc), label) def _operation_cell(self, var_doc): """ :todo: do 'word wrapping' on the signature, by starting a new row in the table, if necessary. How to indent the new line? Maybe use align=right? I don't think dot has a  . :todo: Optionally add return type info? """ # Construct the label (aka function signature) func_doc = var_doc.value args = [self._operation_arg(n, d, func_doc) for (n, d) in zip(func_doc.posargs, func_doc.posarg_defaults)] args = [plaintext_to_html(arg) for arg in args] if func_doc.vararg: args.append('*'+func_doc.vararg) if func_doc.kwarg: args.append('**'+func_doc.kwarg) label = '%s(%s)' % (var_doc.name, ', '.join(args)) # Get the URL url = self.linker.url_for(var_doc) or NOOP_URL # Construct & return the pseudo-html code return self._OPERATION_CELL % (url, self._tooltip(var_doc), label) def _operation_arg(self, name, default, func_doc): """ :todo: Handle tuple args better :todo: Optionally add type info? """ if default is None: return '%s' % name else: pyval_repr = default.summary_pyval_repr().to_plaintext(None) return '%s=%s' % (name, pyval_repr) def _qualifier_cell(self, key_label, port): return self._QUALIFIER_CELL % (port, self.bgcolor, key_label) #: args: (url, tooltip, label) _ATTRIBUTE_CELL = ''' %s ''' #: args: (url, tooltip, label) _OPERATION_CELL = ''' %s ''' #: args: (port, bgcolor, label) _QUALIFIER_CELL = ''' %s ''' _QUALIFIER_DIV = ''' ''' #: Args: (rowspan, bgcolor, classname, attributes, operations, qualifiers) _LABEL = ''' %s
%s
%s
%s
''' _COLLAPSED_LABEL = '''
%s
''' def _get_html_label(self): # Get the class name & contextualize it. classname = self.class_doc.canonical_name classname = classname.contextualize(self.context.canonical_name) # If we're collapsed, display the node as a single box. if self.collapsed: return self._COLLAPSED_LABEL % (self.bgcolor, classname) # Construct the attribute list. (If it's too long, truncate) attrib_cells = [self._attribute_cell(a) for a in self.attributes] max_attributes = self.options.get('max_attributes', 15) if len(attrib_cells) == 0: attrib_cells = [''] elif len(attrib_cells) > max_attributes: attrib_cells[max_attributes-2:-1] = ['...'] attributes = ''.join(attrib_cells) # Construct the operation list. (If it's too long, truncate) oper_cells = [self._operation_cell(a) for a in self.operations] max_operations = self.options.get('max_operations', 15) if len(oper_cells) == 0: oper_cells = [''] elif len(oper_cells) > max_operations: oper_cells[max_operations-2:-1] = ['...'] operations = ''.join(oper_cells) # Construct the qualifier list & determine the rowspan. if self.qualifiers: rowspan = len(self.qualifiers)*2+2 div = self._QUALIFIER_DIV qualifiers = div+div.join([self._qualifier_cell(l,p) for (l,p) in self.qualifiers])+div else: rowspan = 1 qualifiers = '' # Put it all together. return self._LABEL % (rowspan, self.bgcolor, classname, attributes, operations, qualifiers) def to_dotfile(self): attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items()] attribs.append('label=<%s>' % self._get_html_label()) s = 'node%d%s' % (self.id, ' [%s]' % (','.join(attribs))) if not self.collapsed: for edge in self.edges: s += '\n' + edge.to_dotfile() return s class DotGraphUmlModuleNode(DotGraphNode): """ A specialized dot grah node used to display `ModuleDoc`\s using UML notation. Simple module nodes look like:: .----. +------------+ | modulename | +------------+ Packages nodes are drawn with their modules & subpackages nested inside:: .----. +----------------------------------------+ | packagename | | | | .----. .----. .----. | | +---------+ +---------+ +---------+ | | | module1 | | module2 | | module3 | | | +---------+ +---------+ +---------+ | | | +----------------------------------------+ """ def __init__(self, module_doc, linker, context, collapsed=False, excluded_submodules=(), **options): self.module_doc = module_doc self.linker = linker self.context = context self.collapsed = collapsed self.options = options self.excluded_submodules = excluded_submodules DotGraphNode.__init__(self, shape='plaintext', href=linker.url_for(module_doc) or NOOP_URL, tooltip=module_doc.canonical_name) #: Expects: (color, color, url, tooltip, body) _MODULE_LABEL = '''
%s
''' #: Expects: (name, body_rows) _NESTED_BODY = ''' %s
%s
''' #: Expects: (cells,) _NESTED_BODY_ROW = ''' %s
''' def _get_html_label(self, package): """ :Return: (label, depth, width) where: - ``label`` is the HTML label - ``depth`` is the depth of the package tree (for coloring) - ``width`` is the max width of the HTML label, roughly in units of characters. """ MAX_ROW_WIDTH = 80 # unit is roughly characters. pkg_name = package.canonical_name pkg_url = self.linker.url_for(package) or NOOP_URL if (not package.is_package or len(package.submodules) == 0 or self.collapsed): pkg_color = self._color(package, 1) label = self._MODULE_LABEL % (pkg_color, pkg_color, pkg_url, pkg_name, pkg_name[-1]) return (label, 1, len(pkg_name[-1])+3) # Get the label for each submodule, and divide them into rows. row_list = [''] row_width = 0 max_depth = 0 max_row_width = len(pkg_name[-1])+3 for submodule in package.submodules: if submodule in self.excluded_submodules: continue # Get the submodule's label. label, depth, width = self._get_html_label(submodule) # Check if we should start a new row. if row_width > 0 and width+row_width > MAX_ROW_WIDTH: row_list.append('') row_width = 0 # Add the submodule's label to the row. row_width += width row_list[-1] += '%s' % label # Update our max's. max_depth = max(depth, max_depth) max_row_width = max(row_width, max_row_width) # Figure out which color to use. pkg_color = self._color(package, depth+1) # Assemble & return the label. rows = ''.join([self._NESTED_BODY_ROW % r for r in row_list]) body = self._NESTED_BODY % (pkg_name, rows) label = self._MODULE_LABEL % (pkg_color, pkg_color, pkg_url, pkg_name, body) return label, max_depth+1, max_row_width _COLOR_DIFF = 24 def _color(self, package, depth): if package == self.context: return SELECTED_BG else: # Parse the base color. if re.match(MODULE_BG, 'r#[0-9a-fA-F]{6}$'): base = int(MODULE_BG[1:], 16) else: base = int('d8e8ff', 16) red = (base & 0xff0000) >> 16 green = (base & 0x00ff00) >> 8 blue = (base & 0x0000ff) # Make it darker with each level of depth. (but not *too* # dark -- package name needs to be readable) red = max(64, red-(depth-1)*self._COLOR_DIFF) green = max(64, green-(depth-1)*self._COLOR_DIFF) blue = max(64, blue-(depth-1)*self._COLOR_DIFF) # Convert it back to a color string return '#%06x' % ((red<<16)+(green<<8)+blue) def to_dotfile(self): attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items()] label, depth, width = self._get_html_label(self.module_doc) attribs.append('label=<%s>' % label) return 'node%d%s' % (self.id, ' [%s]' % (','.join(attribs))) ###################################################################### #{ Graph Generation Functions ###################################################################### def package_tree_graph(packages, linker, context=None, **options): """ Return a `DotGraph` that graphically displays the package hierarchies for the given packages. """ if options.get('style', 'uml') == 'uml': # default to uml style? if get_dot_version() >= [2]: return uml_package_tree_graph(packages, linker, context, **options) elif 'style' in options: log.warning('UML style package trees require dot version 2.0+') graph = DotGraph('Package Tree for %s' % name_list(packages, context), body='ranksep=.3\n;nodesep=.1\n', edge_defaults={'dir':'none'}) # Options if options.get('dir', 'TB') != 'TB': # default: top-to-bottom graph.body += 'rankdir=%s\n' % options.get('dir', 'TB') # Get a list of all modules in the package. queue = list(packages) modules = set(packages) for module in queue: queue.extend(module.submodules) modules.update(module.submodules) # Add a node for each module. nodes = add_valdoc_nodes(graph, modules, linker, context) # Add an edge for each package/submodule relationship. for module in modules: for submodule in module.submodules: graph.edges.append(DotGraphEdge(nodes[module], nodes[submodule], headport='tab')) return graph def uml_package_tree_graph(packages, linker, context=None, **options): """ Return a `DotGraph` that graphically displays the package hierarchies for the given packages as a nested set of UML symbols. """ graph = DotGraph('Package Tree for %s' % name_list(packages, context)) # Remove any packages whose containers are also in the list. root_packages = [] for package1 in packages: for package2 in packages: if (package1 is not package2 and package2.canonical_name.dominates(package1.canonical_name)): break else: root_packages.append(package1) # If the context is a variable, then get its value. if isinstance(context, VariableDoc) and context.value is not UNKNOWN: context = context.value # Return a graph with one node for each root package. for package in root_packages: graph.nodes.append(DotGraphUmlModuleNode(package, linker, context)) return graph ###################################################################### def class_tree_graph(bases, linker, context=None, **options): """ Return a `DotGraph` that graphically displays the class hierarchy for the given classes. Options: - exclude - dir: LR|RL|BT requests a left-to-right, right-to-left, or bottom-to- top, drawing. (corresponds to the dot option 'rankdir' """ if isinstance(bases, ClassDoc): bases = [bases] graph = DotGraph('Class Hierarchy for %s' % name_list(bases, context), body='ranksep=0.3\n', edge_defaults={'sametail':True, 'dir':'none'}) # Options if options.get('dir', 'TB') != 'TB': # default: top-down graph.body += 'rankdir=%s\n' % options.get('dir', 'TB') exclude = options.get('exclude', ()) # Find all superclasses & subclasses of the given classes. classes = set(bases) queue = list(bases) for cls in queue: if isinstance(cls, ClassDoc): if cls.subclasses not in (None, UNKNOWN): subclasses = cls.subclasses if exclude: subclasses = [d for d in subclasses if d not in exclude] queue.extend(subclasses) classes.update(subclasses) queue = list(bases) for cls in queue: if isinstance(cls, ClassDoc): if cls.bases not in (None, UNKNOWN): bases = cls.bases if exclude: bases = [d for d in bases if d not in exclude] queue.extend(bases) classes.update(bases) # Add a node for each cls. classes = [d for d in classes if isinstance(d, ClassDoc) if d.pyval is not object] nodes = add_valdoc_nodes(graph, classes, linker, context) # Add an edge for each package/subclass relationship. edges = set() for cls in classes: for subcls in cls.subclasses: if cls in nodes and subcls in nodes: edges.add((nodes[cls], nodes[subcls])) graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] return graph ###################################################################### def uml_class_tree_graph(class_doc, linker, context=None, **options): """ Return a `DotGraph` that graphically displays the class hierarchy for the given class, using UML notation. Options: - max_attributes - max_operations - show_private_vars - show_magic_vars - link_attributes """ nodes = {} # ClassDoc -> DotGraphUmlClassNode exclude = options.get('exclude', ()) # Create nodes for class_doc and all its bases. for cls in class_doc.mro(): if cls.pyval is object: continue # don't include `object`. if cls in exclude: break # stop if we get to an excluded class. if cls == class_doc: color = SELECTED_BG else: color = BASECLASS_BG nodes[cls] = DotGraphUmlClassNode(cls, linker, context, show_inherited_vars=False, collapsed=False, bgcolor=color) # Create nodes for all class_doc's subclasses. queue = [class_doc] for cls in queue: if (isinstance(cls, ClassDoc) and cls.subclasses not in (None, UNKNOWN)): for subcls in cls.subclasses: subcls_name = subcls.canonical_name[-1] if subcls not in nodes and subcls not in exclude: queue.append(subcls) nodes[subcls] = DotGraphUmlClassNode( subcls, linker, context, collapsed=True, bgcolor=SUBCLASS_BG) # Only show variables in the class where they're defined for # *class_doc*. mro = class_doc.mro() for name, var in class_doc.variables.items(): i = mro.index(var.container) for base in mro[i+1:]: if base.pyval is object: continue # don't include `object`. overridden_var = base.variables.get(name) if overridden_var and overridden_var.container == base: try: if isinstance(overridden_var.value, RoutineDoc): nodes[base].operations.remove(overridden_var) else: nodes[base].attributes.remove(overridden_var) except ValueError: pass # var is filtered (eg private or magic) # Keep track of which nodes are part of the inheritance graph # (since link_attributes might add new nodes) inheritance_nodes = set(nodes.values()) # Turn attributes into links. if options.get('link_attributes', True): for node in nodes.values(): node.link_attributes(nodes) # Make sure that none of the new attribute edges break the # rank ordering assigned by inheritance. for edge in node.edges: if edge.end in inheritance_nodes: edge['constraint'] = 'False' # Construct the graph. graph = DotGraph('UML class diagram for %s' % class_doc.canonical_name, body='ranksep=.2\n;nodesep=.3\n') graph.nodes = nodes.values() # Add inheritance edges. for node in inheritance_nodes: for base in node.class_doc.bases: if base in nodes: graph.edges.append(DotGraphEdge(nodes[base], node, dir='back', arrowtail='empty', headport='body', tailport='body', color=INH_LINK_COLOR, weight=100, style='bold')) # And we're done! return graph ###################################################################### def import_graph(modules, docindex, linker, context=None, **options): graph = DotGraph('Import Graph', body='ranksep=.3\n;nodesep=.3\n') # Options if options.get('dir', 'RL') != 'TB': # default: right-to-left. graph.body += 'rankdir=%s\n' % options.get('dir', 'RL') # Add a node for each module. nodes = add_valdoc_nodes(graph, modules, linker, context) # Edges. edges = set() for dst in modules: if dst.imports in (None, UNKNOWN): continue for var_name in dst.imports: for i in range(len(var_name), 0, -1): val_doc = docindex.find(var_name[:i], context) if isinstance(val_doc, ModuleDoc): if val_doc in nodes and dst in nodes: edges.add((nodes[val_doc], nodes[dst])) break graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] return graph ###################################################################### def call_graph(api_docs, docindex, linker, context=None, **options): """ :param options: - ``dir``: rankdir for the graph. (default=LR) - ``add_callers``: also include callers for any of the routines in ``api_docs``. (default=False) - ``add_callees``: also include callees for any of the routines in ``api_docs``. (default=False) :todo: Add an ``exclude`` option? """ if docindex.callers is None: log.warning("No profiling information for call graph!") return DotGraph('Call Graph') # return None instead? if isinstance(context, VariableDoc): context = context.value # Get the set of requested functions. functions = [] for api_doc in api_docs: # If it's a variable, get its value. if isinstance(api_doc, VariableDoc): api_doc = api_doc.value # Add the value to the functions list. if isinstance(api_doc, RoutineDoc): functions.append(api_doc) elif isinstance(api_doc, NamespaceDoc): for vardoc in api_doc.variables.values(): if isinstance(vardoc.value, RoutineDoc): functions.append(vardoc.value) # Filter out functions with no callers/callees? # [xx] this isnt' quite right, esp if add_callers or add_callees # options are fales. functions = [f for f in functions if (f in docindex.callers) or (f in docindex.callees)] # Add any callers/callees of the selected functions func_set = set(functions) if options.get('add_callers', False) or options.get('add_callees', False): for func_doc in functions: if options.get('add_callers', False): func_set.update(docindex.callers.get(func_doc, ())) if options.get('add_callees', False): func_set.update(docindex.callees.get(func_doc, ())) graph = DotGraph('Call Graph for %s' % name_list(api_docs, context), node_defaults={'shape':'box', 'width': 0, 'height': 0}) # Options if options.get('dir', 'LR') != 'TB': # default: left-to-right graph.body += 'rankdir=%s\n' % options.get('dir', 'LR') nodes = add_valdoc_nodes(graph, func_set, linker, context) # Find the edges. edges = set() for func_doc in functions: for caller in docindex.callers.get(func_doc, ()): if caller in nodes: edges.add( (nodes[caller], nodes[func_doc]) ) for callee in docindex.callees.get(func_doc, ()): if callee in nodes: edges.add( (nodes[func_doc], nodes[callee]) ) graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] return graph ###################################################################### #{ Dot Version ###################################################################### _dot_version = None _DOT_VERSION_RE = re.compile(r'dot version ([\d\.]+)') def get_dot_version(): global _dot_version if _dot_version is None: try: out, err = run_subprocess([DOT_COMMAND, '-V']) version_info = err or out m = _DOT_VERSION_RE.match(version_info) if m: _dot_version = [int(x) for x in m.group(1).split('.')] else: _dot_version = (0,) except OSError, e: _dot_version = (0,) log.info('Detected dot version %s' % _dot_version) return _dot_version ###################################################################### #{ Helper Functions ###################################################################### def add_valdoc_nodes(graph, val_docs, linker, context): """ :todo: Use different node styles for different subclasses of APIDoc """ nodes = {} val_docs = sorted(val_docs, key=lambda d:d.canonical_name) for i, val_doc in enumerate(val_docs): label = val_doc.canonical_name.contextualize(context.canonical_name) node = nodes[val_doc] = DotGraphNode(label) graph.nodes.append(node) specialize_valdoc_node(node, val_doc, context, linker.url_for(val_doc)) return nodes NOOP_URL = 'javascript:void(0);' MODULE_NODE_HTML = '''
%s
'''.strip() def specialize_valdoc_node(node, val_doc, context, url): """ Update the style attributes of `node` to reflext its type and context. """ # We can only use html-style nodes if dot_version>2. dot_version = get_dot_version() # If val_doc or context is a variable, get its value. if isinstance(val_doc, VariableDoc) and val_doc.value is not UNKNOWN: val_doc = val_doc.value if isinstance(context, VariableDoc) and context.value is not UNKNOWN: context = context.value # Set the URL. (Do this even if it points to the page we're # currently on; otherwise, the tooltip is ignored.) node['href'] = url or NOOP_URL if isinstance(val_doc, ModuleDoc) and dot_version >= [2]: node['shape'] = 'plaintext' if val_doc == context: color = SELECTED_BG else: color = MODULE_BG node['tooltip'] = node['label'] node['html_label'] = MODULE_NODE_HTML % (color, color, url, val_doc.canonical_name, node['label']) node['width'] = node['height'] = 0 node.port = 'body' elif isinstance(val_doc, RoutineDoc): node['shape'] = 'box' node['style'] = 'rounded' node['width'] = 0 node['height'] = 0 node['label'] = '%s()' % node['label'] node['tooltip'] = node['label'] if val_doc == context: node['fillcolor'] = SELECTED_BG node['style'] = 'filled,rounded,bold' else: node['shape'] = 'box' node['width'] = 0 node['height'] = 0 node['tooltip'] = node['label'] if val_doc == context: node['fillcolor'] = SELECTED_BG node['style'] = 'filled,bold' def name_list(api_docs, context=None): if context is not None: context = context.canonical_name names = [str(d.canonical_name.contextualize(context)) for d in api_docs] if len(names) == 0: return '' if len(names) == 1: return '%s' % names[0] elif len(names) == 2: return '%s and %s' % (names[0], names[1]) else: return '%s, and %s' % (', '.join(names[:-1]), names[-1]) epydoc-3.0.1+dfsg/epydoc/docwriter/latex.py0000644000175000017500000013657310675533140021174 0ustar pronovicpronovic# # epydoc.py: epydoc LaTeX output generator # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: latex.py 1621 2007-09-23 18:54:23Z edloper $ # """ The LaTeX output generator for epydoc. The main interface provided by this module is the L{LatexWriter} class. @todo: Inheritance=listed """ __docformat__ = 'epytext en' import os.path, sys, time, re, textwrap, codecs from epydoc.apidoc import * from epydoc.compat import * import epydoc from epydoc import log from epydoc import markup from epydoc.util import plaintext_to_latex import epydoc.markup class LatexWriter: PREAMBLE = [ "\\documentclass{article}", "\\usepackage{alltt, parskip, fancyhdr, boxedminipage}", "\\usepackage{makeidx, multirow, longtable, tocbibind, amssymb}", "\\usepackage{fullpage}", "\\usepackage[usenames]{color}", # Fix the heading position -- without this, the headings generated # by the fancyheadings package sometimes overlap the text. "\\setlength{\\headheight}{16pt}", "\\setlength{\\headsep}{24pt}", "\\setlength{\\topmargin}{-\\headsep}", # By default, do not indent paragraphs. "\\setlength{\\parindent}{0ex}", "\\setlength{\\parskip}{2ex}", # Double the standard size boxedminipage outlines. "\\setlength{\\fboxrule}{2\\fboxrule}", # Create a 'base class' length named BCL for use in base trees. "\\newlength{\\BCL} % base class length, for base trees.", # Display the section & subsection names in a header. "\\pagestyle{fancy}", "\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}", "\\renewcommand{\\subsectionmark}[1]{\\markright{#1}}", # Colorization for python source code "\\definecolor{py@keywordcolour}{rgb}{1,0.45882,0}", "\\definecolor{py@stringcolour}{rgb}{0,0.666666,0}", "\\definecolor{py@commentcolour}{rgb}{1,0,0}", "\\definecolor{py@ps1colour}{rgb}{0.60784,0,0}", "\\definecolor{py@ps2colour}{rgb}{0.60784,0,1}", "\\definecolor{py@inputcolour}{rgb}{0,0,0}", "\\definecolor{py@outputcolour}{rgb}{0,0,1}", "\\definecolor{py@exceptcolour}{rgb}{1,0,0}", "\\definecolor{py@defnamecolour}{rgb}{1,0.5,0.5}", "\\definecolor{py@builtincolour}{rgb}{0.58039,0,0.58039}", "\\definecolor{py@identifiercolour}{rgb}{0,0,0}", "\\definecolor{py@linenumcolour}{rgb}{0.4,0.4,0.4}", "\\definecolor{py@inputcolour}{rgb}{0,0,0}", "% Prompt", "\\newcommand{\\pysrcprompt}[1]{\\textcolor{py@ps1colour}" "{\\small\\textbf{#1}}}", "\\newcommand{\\pysrcmore}[1]{\\textcolor{py@ps2colour}" "{\\small\\textbf{#1}}}", "% Source code", "\\newcommand{\\pysrckeyword}[1]{\\textcolor{py@keywordcolour}" "{\\small\\textbf{#1}}}", "\\newcommand{\\pysrcbuiltin}[1]{\\textcolor{py@builtincolour}" "{\\small\\textbf{#1}}}", "\\newcommand{\\pysrcstring}[1]{\\textcolor{py@stringcolour}" "{\\small\\textbf{#1}}}", "\\newcommand{\\pysrcdefname}[1]{\\textcolor{py@defnamecolour}" "{\\small\\textbf{#1}}}", "\\newcommand{\\pysrcother}[1]{\\small\\textbf{#1}}", "% Comments", "\\newcommand{\\pysrccomment}[1]{\\textcolor{py@commentcolour}" "{\\small\\textbf{#1}}}", "% Output", "\\newcommand{\\pysrcoutput}[1]{\\textcolor{py@outputcolour}" "{\\small\\textbf{#1}}}", "% Exceptions", "\\newcommand{\\pysrcexcept}[1]{\\textcolor{py@exceptcolour}" "{\\small\\textbf{#1}}}", # Size of the function description boxes. "\\newlength{\\funcindent}", "\\newlength{\\funcwidth}", "\\setlength{\\funcindent}{1cm}", "\\setlength{\\funcwidth}{\\textwidth}", "\\addtolength{\\funcwidth}{-2\\funcindent}", # Size of the var description tables. "\\newlength{\\varindent}", "\\newlength{\\varnamewidth}", "\\newlength{\\vardescrwidth}", "\\newlength{\\varwidth}", "\\setlength{\\varindent}{1cm}", "\\setlength{\\varnamewidth}{.3\\textwidth}", "\\setlength{\\varwidth}{\\textwidth}", "\\addtolength{\\varwidth}{-4\\tabcolsep}", "\\addtolength{\\varwidth}{-3\\arrayrulewidth}", "\\addtolength{\\varwidth}{-2\\varindent}", "\\setlength{\\vardescrwidth}{\\varwidth}", "\\addtolength{\\vardescrwidth}{-\\varnamewidth}", # Define new environment for displaying parameter lists. textwrap.dedent("""\ \\newenvironment{Ventry}[1]% {\\begin{list}{}{% \\renewcommand{\\makelabel}[1]{\\texttt{##1:}\\hfil}% \\settowidth{\\labelwidth}{\\texttt{#1:}}% \\setlength{\\leftmargin}{\\labelsep}% \\addtolength{\\leftmargin}{\\labelwidth}}}% {\\end{list}}"""), ] HRULE = '\\rule{\\textwidth}{0.5\\fboxrule}\n\n' SECTIONS = ['\\part{%s}', '\\chapter{%s}', '\\section{%s}', '\\subsection{%s}', '\\subsubsection{%s}', '\\textbf{%s}'] STAR_SECTIONS = ['\\part*{%s}', '\\chapter*{%s}', '\\section*{%s}', '\\subsection*{%s}', '\\subsubsection*{%s}', '\\textbf{%s}'] def __init__(self, docindex, **kwargs): self.docindex = docindex # Process keyword arguments self._show_private = kwargs.get('private', 0) self._prj_name = kwargs.get('prj_name', None) or 'API Documentation' self._crossref = kwargs.get('crossref', 1) self._index = kwargs.get('index', 1) self._list_classes_separately=kwargs.get('list_classes_separately',0) self._inheritance = kwargs.get('inheritance', 'listed') self._exclude = kwargs.get('exclude', 1) self._top_section = 2 self._index_functions = 1 self._hyperref = 1 #: The Python representation of the encoding. #: Update L{latex_encodings} in case of mismatch between it and #: the C{inputenc} LaTeX package. self._encoding = kwargs.get('encoding', 'utf-8') self.valdocs = valdocs = sorted(docindex.reachable_valdocs( imports=False, packages=False, bases=False, submodules=False, subclasses=False, private=self._show_private)) self._num_files = self.num_files() # For use with select_variables(): if self._show_private: self._public_filter = None else: self._public_filter = True self.class_list = [d for d in valdocs if isinstance(d, ClassDoc)] """The list of L{ClassDoc}s for the documented classes.""" self.class_set = set(self.class_list) """The set of L{ClassDoc}s for the documented classes.""" def write(self, directory=None): """ Write the API documentation for the entire project to the given directory. @type directory: C{string} @param directory: The directory to which output should be written. If no directory is specified, output will be written to the current directory. If the directory does not exist, it will be created. @rtype: C{None} @raise OSError: If C{directory} cannot be created, @raise OSError: If any file cannot be created or written to. """ # For progress reporting: self._files_written = 0. # Set the default values for ValueDoc formatted representations. orig_valdoc_defaults = (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, ValueDoc.REPR_MAXLINES) ValueDoc.SUMMARY_REPR_LINELEN = 60 ValueDoc.REPR_LINELEN = 52 ValueDoc.REPR_MAXLINES = 5 # Create destination directories, if necessary if not directory: directory = os.curdir self._mkdir(directory) self._directory = directory # Write the top-level file. self._write(self.write_topfile, directory, 'api.tex') # Write the module & class files. for val_doc in self.valdocs: if isinstance(val_doc, ModuleDoc): filename = '%s-module.tex' % val_doc.canonical_name self._write(self.write_module, directory, filename, val_doc) elif (isinstance(val_doc, ClassDoc) and self._list_classes_separately): filename = '%s-class.tex' % val_doc.canonical_name self._write(self.write_class, directory, filename, val_doc) # Restore defaults that we changed. (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, ValueDoc.REPR_MAXLINES) = orig_valdoc_defaults def _write(self, write_func, directory, filename, *args): # Display our progress. self._files_written += 1 log.progress(self._files_written/self._num_files, filename) path = os.path.join(directory, filename) if self._encoding == 'utf-8': f = codecs.open(path, 'w', 'utf-8') write_func(f.write, *args) f.close() else: result = [] write_func(result.append, *args) s = u''.join(result) try: s = s.encode(self._encoding) except UnicodeError: log.error("Output could not be represented with the " "given encoding (%r). Unencodable characters " "will be displayed as '?'. It is recommended " "that you use a different output encoding (utf-8, " "if it's supported by latex on your system)." % self._encoding) s = s.encode(self._encoding, 'replace') f = open(path, 'w') f.write(s) f.close() def num_files(self): """ @return: The number of files that this C{LatexFormatter} will generate. @rtype: C{int} """ n = 1 for doc in self.valdocs: if isinstance(doc, ModuleDoc): n += 1 if isinstance(doc, ClassDoc) and self._list_classes_separately: n += 1 return n def _mkdir(self, directory): """ If the given directory does not exist, then attempt to create it. @rtype: C{None} """ if not os.path.isdir(directory): if os.path.exists(directory): raise OSError('%r is not a directory' % directory) os.mkdir(directory) #//////////////////////////////////////////////////////////// #{ Main Doc File #//////////////////////////////////////////////////////////// def write_topfile(self, out): self.write_header(out, 'Include File') self.write_preamble(out) out('\n\\begin{document}\n\n') self.write_start_of(out, 'Header') # Write the title. self.write_start_of(out, 'Title') out('\\title{%s}\n' % plaintext_to_latex(self._prj_name, 1)) out('\\author{API Documentation}\n') out('\\maketitle\n') # Add a table of contents. self.write_start_of(out, 'Table of Contents') out('\\addtolength{\\parskip}{-2ex}\n') out('\\tableofcontents\n') out('\\addtolength{\\parskip}{2ex}\n') # Include documentation files. self.write_start_of(out, 'Includes') for val_doc in self.valdocs: if isinstance(val_doc, ModuleDoc): out('\\include{%s-module}\n' % val_doc.canonical_name) # If we're listing classes separately, put them after all the # modules. if self._list_classes_separately: for val_doc in self.valdocs: if isinstance(val_doc, ClassDoc): out('\\include{%s-class}\n' % val_doc.canonical_name) # Add the index, if requested. if self._index: self.write_start_of(out, 'Index') out('\\printindex\n\n') # Add the footer. self.write_start_of(out, 'Footer') out('\\end{document}\n\n') def write_preamble(self, out): out('\n'.join(self.PREAMBLE)) out('\n') # Set the encoding. out('\\usepackage[%s]{inputenc}\n' % self.get_latex_encoding()) # If we're generating hyperrefs, add the appropriate packages. if self._hyperref: out('\\definecolor{UrlColor}{rgb}{0,0.08,0.45}\n') out('\\usepackage[dvips, pagebackref, pdftitle={%s}, ' 'pdfcreator={epydoc %s}, bookmarks=true, ' 'bookmarksopen=false, pdfpagemode=UseOutlines, ' 'colorlinks=true, linkcolor=black, anchorcolor=black, ' 'citecolor=black, filecolor=black, menucolor=black, ' 'pagecolor=black, urlcolor=UrlColor]{hyperref}\n' % (self._prj_name or '', epydoc.__version__)) # If we're generating an index, add it to the preamble. if self._index: out("\\makeindex\n") # If restructuredtext was used, then we need to extend # the prefix to include LatexTranslator.head_prefix. if 'restructuredtext' in epydoc.markup.MARKUP_LANGUAGES_USED: from epydoc.markup import restructuredtext rst_head = restructuredtext.latex_head_prefix() rst_head = ''.join(rst_head).split('\n') for line in rst_head[1:]: m = re.match(r'\\usepackage(\[.*?\])?{(.*?)}', line) if m and m.group(2) in ( 'babel', 'hyperref', 'color', 'alltt', 'parskip', 'fancyhdr', 'boxedminipage', 'makeidx', 'multirow', 'longtable', 'tocbind', 'assymb', 'fullpage', 'inputenc'): pass else: out(line+'\n') #//////////////////////////////////////////////////////////// #{ Chapters #//////////////////////////////////////////////////////////// def write_module(self, out, doc): self.write_header(out, doc) self.write_start_of(out, 'Module Description') # Add this module to the index. out(' ' + self.indexterm(doc, 'start')) # Add a section marker. out(self.section('%s %s' % (self.doc_kind(doc), doc.canonical_name))) # Label our current location. out(' \\label{%s}\n' % self.label(doc)) # Add the module's description. if doc.descr not in (None, UNKNOWN): out(self.docstring_to_latex(doc.descr)) # Add version, author, warnings, requirements, notes, etc. self.write_standard_fields(out, doc) # If it's a package, list the sub-modules. if doc.submodules != UNKNOWN and doc.submodules: self.write_module_list(out, doc) # Contents. if self._list_classes_separately: self.write_class_list(out, doc) self.write_func_list(out, 'Functions', doc, 'function') self.write_var_list(out, 'Variables', doc, 'other') # Class list. if not self._list_classes_separately: classes = doc.select_variables(imported=False, value_type='class', public=self._public_filter) for var_doc in classes: self.write_class(out, var_doc.value) # Mark the end of the module (for the index) out(' ' + self.indexterm(doc, 'end')) def write_class(self, out, doc): if self._list_classes_separately: self.write_header(out, doc) self.write_start_of(out, 'Class Description') # Add this class to the index. out(' ' + self.indexterm(doc, 'start')) # Add a section marker. if self._list_classes_separately: seclevel = 0 out(self.section('%s %s' % (self.doc_kind(doc), doc.canonical_name), seclevel)) else: seclevel = 1 out(self.section('%s %s' % (self.doc_kind(doc), doc.canonical_name[-1]), seclevel)) # Label our current location. out(' \\label{%s}\n' % self.label(doc)) # Add our base list. if doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0: out(self.base_tree(doc)) # The class's known subclasses if doc.subclasses not in (UNKNOWN, None) and len(doc.subclasses) > 0: sc_items = [plaintext_to_latex('%s' % sc.canonical_name) for sc in doc.subclasses] out(self._descrlist(sc_items, 'Known Subclasses', short=1)) # The class's description. if doc.descr not in (None, UNKNOWN): out(self.docstring_to_latex(doc.descr)) # Version, author, warnings, requirements, notes, etc. self.write_standard_fields(out, doc) # Contents. self.write_func_list(out, 'Methods', doc, 'method', seclevel+1) self.write_var_list(out, 'Properties', doc, 'property', seclevel+1) self.write_var_list(out, 'Class Variables', doc, 'classvariable', seclevel+1) self.write_var_list(out, 'Instance Variables', doc, 'instancevariable', seclevel+1) # Mark the end of the class (for the index) out(' ' + self.indexterm(doc, 'end')) #//////////////////////////////////////////////////////////// #{ Module hierarchy trees #//////////////////////////////////////////////////////////// def write_module_tree(self, out): modules = [doc for doc in self.valdocs if isinstance(doc, ModuleDoc)] if not modules: return # Write entries for all top-level modules/packages. out('\\begin{itemize}\n') out('\\setlength{\\parskip}{0ex}\n') for doc in modules: if (doc.package in (None, UNKNOWN) or doc.package not in self.valdocs): self.write_module_tree_item(out, doc) return s +'\\end{itemize}\n' def write_module_list(self, out, doc): if len(doc.submodules) == 0: return self.write_start_of(out, 'Modules') out(self.section('Modules', 1)) out('\\begin{itemize}\n') out('\\setlength{\\parskip}{0ex}\n') for group_name in doc.group_names(): if not doc.submodule_groups[group_name]: continue if group_name: out(' \\item \\textbf{%s}\n' % group_name) out(' \\begin{itemize}\n') for submodule in doc.submodule_groups[group_name]: self.write_module_tree_item(out, submodule) if group_name: out(' \end{itemize}\n') out('\\end{itemize}\n\n') def write_module_tree_item(self, out, doc, depth=0): """ Helper function for L{write_module_tree} and L{write_module_list}. @rtype: C{string} """ out(' '*depth + '\\item \\textbf{') out(plaintext_to_latex(doc.canonical_name[-1]) +'}') if doc.summary not in (None, UNKNOWN): out(': %s\n' % self.docstring_to_latex(doc.summary)) if self._crossref: out('\n \\textit{(Section \\ref{%s}' % self.label(doc)) out(', p.~\\pageref{%s})}\n\n' % self.label(doc)) if doc.submodules != UNKNOWN and doc.submodules: out(' '*depth + ' \\begin{itemize}\n') out(' '*depth + '\\setlength{\\parskip}{0ex}\n') for submodule in doc.submodules: self.write_module_tree_item(out, submodule, depth+4) out(' '*depth + ' \\end{itemize}\n') #//////////////////////////////////////////////////////////// #{ Base class trees #//////////////////////////////////////////////////////////// def base_tree(self, doc, width=None, linespec=None): if width is None: width = self._find_tree_width(doc)+2 linespec = [] s = ('&'*(width-4)+'\\multicolumn{2}{l}{\\textbf{%s}}\n' % plaintext_to_latex('%s'%self._base_name(doc))) s += '\\end{tabular}\n\n' top = 1 else: s = self._base_tree_line(doc, width, linespec) top = 0 if isinstance(doc, ClassDoc): for i in range(len(doc.bases)-1, -1, -1): base = doc.bases[i] spec = (i > 0) s = self.base_tree(base, width, [spec]+linespec) + s if top: s = '\\begin{tabular}{%s}\n' % (width*'c') + s return s def _base_name(self, doc): if doc.canonical_name is None: if doc.parse_repr is not None: return doc.parse_repr else: return '??' else: return '%s' % doc.canonical_name def _find_tree_width(self, doc): if not isinstance(doc, ClassDoc): return 2 width = 2 for base in doc.bases: width = max(width, self._find_tree_width(base)+2) return width def _base_tree_line(self, doc, width, linespec): base_name = plaintext_to_latex(self._base_name(doc)) # linespec is a list of booleans. s = '%% Line for %s, linespec=%s\n' % (base_name, linespec) labelwidth = width-2*len(linespec)-2 # The base class name. s += ('\\multicolumn{%s}{r}{' % labelwidth) s += '\\settowidth{\\BCL}{%s}' % base_name s += '\\multirow{2}{\\BCL}{%s}}\n' % base_name # The vertical bars for other base classes (top half) for vbar in linespec: if vbar: s += '&&\\multicolumn{1}{|c}{}\n' else: s += '&&\n' # The horizontal line. s += ' \\\\\\cline{%s-%s}\n' % (labelwidth+1, labelwidth+1) # The vertical bar for this base class. s += ' ' + '&'*labelwidth s += '\\multicolumn{1}{c|}{}\n' # The vertical bars for other base classes (bottom half) for vbar in linespec: if vbar: s += '&\\multicolumn{1}{|c}{}&\n' else: s += '&&\n' s += ' \\\\\n' return s #//////////////////////////////////////////////////////////// #{ Class List #//////////////////////////////////////////////////////////// def write_class_list(self, out, doc): groups = [(plaintext_to_latex(group_name), doc.select_variables(group=group_name, imported=False, value_type='class', public=self._public_filter)) for group_name in doc.group_names()] # Discard any empty groups; and return if they're all empty. groups = [(g,vars) for (g,vars) in groups if vars] if not groups: return # Write a header. self.write_start_of(out, 'Classes') out(self.section('Classes', 1)) out('\\begin{itemize}') out(' \\setlength{\\parskip}{0ex}\n') for name, var_docs in groups: if name: out(' \\item \\textbf{%s}\n' % name) out(' \\begin{itemize}\n') # Add the lines for each class for var_doc in var_docs: self.write_class_list_line(out, var_doc) if name: out(' \\end{itemize}\n') out('\\end{itemize}\n') def write_class_list_line(self, out, var_doc): if var_doc.value in (None, UNKNOWN): return # shouldn't happen doc = var_doc.value out(' ' + '\\item \\textbf{') out(plaintext_to_latex(var_doc.name) + '}') if doc.summary not in (None, UNKNOWN): out(': %s\n' % self.docstring_to_latex(doc.summary)) if self._crossref: out(('\n \\textit{(Section \\ref{%s}' % self.label(doc))) out((', p.~\\pageref{%s})}\n\n' % self.label(doc))) #//////////////////////////////////////////////////////////// #{ Function List #//////////////////////////////////////////////////////////// _FUNC_GROUP_HEADER = '\n\\large{\\textbf{\\textit{%s}}}\n\n' def write_func_list(self, out, heading, doc, value_type, seclevel=1): # Divide all public variables of the given type into groups. groups = [(plaintext_to_latex(group_name), doc.select_variables(group=group_name, imported=False, value_type=value_type, public=self._public_filter)) for group_name in doc.group_names()] # Discard any empty groups; and return if they're all empty. groups = [(g,vars) for (g,vars) in groups if vars] if not groups: return # Write a header. self.write_start_of(out, heading) out(' '+self.section(heading, seclevel)) # Write a section for each group. grouped_inh_vars = {} for name, var_docs in groups: self.write_func_group(out, doc, name, var_docs, grouped_inh_vars) # Write a section for each inheritance pseudo-group (used if # inheritance=='grouped') if grouped_inh_vars: for base in doc.mro(): if base in grouped_inh_vars: hdr = ('Inherited from %s' % plaintext_to_latex('%s' % base.canonical_name)) if self._crossref and base in self.class_set: hdr += ('\\textit{(Section \\ref{%s})}' % self.label(base)) out(self._FUNC_GROUP_HEADER % (hdr)) for var_doc in grouped_inh_vars[base]: self.write_func_list_box(out, var_doc) def write_func_group(self, out, doc, name, var_docs, grouped_inh_vars): # Split up the var_docs list, according to the way each var # should be displayed: # - listed_inh_vars -- for listed inherited variables. # - grouped_inh_vars -- for grouped inherited variables. # - normal_vars -- for all other variables. listed_inh_vars = {} normal_vars = [] for var_doc in var_docs: if var_doc.container != doc: base = var_doc.container if (base not in self.class_set or self._inheritance == 'listed'): listed_inh_vars.setdefault(base,[]).append(var_doc) elif self._inheritance == 'grouped': grouped_inh_vars.setdefault(base,[]).append(var_doc) else: normal_vars.append(var_doc) else: normal_vars.append(var_doc) # Write a header for the group. if name: out(self._FUNC_GROUP_HEADER % name) # Write an entry for each normal var: for var_doc in normal_vars: self.write_func_list_box(out, var_doc) # Write a subsection for inherited vars: if listed_inh_vars: self.write_func_inheritance_list(out, doc, listed_inh_vars) def write_func_inheritance_list(self, out, doc, listed_inh_vars): for base in doc.mro(): if base not in listed_inh_vars: continue #if str(base.canonical_name) == 'object': continue var_docs = listed_inh_vars[base] if self._public_filter: var_docs = [v for v in var_docs if v.is_public] if var_docs: hdr = ('Inherited from %s' % plaintext_to_latex('%s' % base.canonical_name)) if self._crossref and base in self.class_set: hdr += ('\\textit{(Section \\ref{%s})}' % self.label(base)) out(self._FUNC_GROUP_HEADER % hdr) out('\\begin{quote}\n') out('%s\n' % ', '.join( ['%s()' % plaintext_to_latex(var_doc.name) for var_doc in var_docs])) out('\\end{quote}\n') def write_func_list_box(self, out, var_doc): func_doc = var_doc.value is_inherited = (var_doc.overrides not in (None, UNKNOWN)) # nb: this gives the containing section, not a reference # directly to the function. if not is_inherited: out(' \\label{%s}\n' % self.label(func_doc)) out(' %s\n' % self.indexterm(func_doc)) # Start box for this function. out(' \\vspace{0.5ex}\n\n') out('\\hspace{.8\\funcindent}') out('\\begin{boxedminipage}{\\funcwidth}\n\n') # Function signature. out(' %s\n\n' % self.function_signature(var_doc)) if (func_doc.docstring not in (None, UNKNOWN) and func_doc.docstring.strip() != ''): out(' \\vspace{-1.5ex}\n\n') out(' \\rule{\\textwidth}{0.5\\fboxrule}\n') # Description out("\\setlength{\\parskip}{2ex}\n") if func_doc.descr not in (None, UNKNOWN): out(self.docstring_to_latex(func_doc.descr, 4)) # Parameters out("\\setlength{\\parskip}{1ex}\n") if func_doc.arg_descrs or func_doc.arg_types: # Find the longest name. longest = max([0]+[len(n) for n in func_doc.arg_types]) for names, descrs in func_doc.arg_descrs: longest = max([longest]+[len(n) for n in names]) # Table header. out(' '*6+'\\textbf{Parameters}\n') out(' \\vspace{-1ex}\n\n') out(' '*6+'\\begin{quote}\n') out(' \\begin{Ventry}{%s}\n\n' % (longest*'x')) # Add params that have @type but not @param info: arg_descrs = list(func_doc.arg_descrs) args = set() for arg_names, arg_descr in arg_descrs: args.update(arg_names) for arg in var_doc.value.arg_types: if arg not in args: arg_descrs.append( ([arg],None) ) # Display params for (arg_names, arg_descr) in arg_descrs: arg_name = plaintext_to_latex(', '.join(arg_names)) out('%s\\item[%s]\n\n' % (' '*10, arg_name)) if arg_descr: out(self.docstring_to_latex(arg_descr, 10)) for arg_name in arg_names: arg_typ = func_doc.arg_types.get(arg_name) if arg_typ is not None: if len(arg_names) == 1: lhs = 'type' else: lhs = 'type of %s' % arg_name rhs = self.docstring_to_latex(arg_typ).strip() out('%s{\\it (%s=%s)}\n\n' % (' '*12, lhs, rhs)) out(' \\end{Ventry}\n\n') out(' '*6+'\\end{quote}\n\n') # Returns rdescr = func_doc.return_descr rtype = func_doc.return_type if rdescr not in (None, UNKNOWN) or rtype not in (None, UNKNOWN): out(' '*6+'\\textbf{Return Value}\n') out(' \\vspace{-1ex}\n\n') out(' '*6+'\\begin{quote}\n') if rdescr not in (None, UNKNOWN): out(self.docstring_to_latex(rdescr, 6)) if rtype not in (None, UNKNOWN): out(' '*6+'{\\it (type=%s)}\n\n' % self.docstring_to_latex(rtype, 6).strip()) elif rtype not in (None, UNKNOWN): out(self.docstring_to_latex(rtype, 6)) out(' '*6+'\\end{quote}\n\n') # Raises if func_doc.exception_descrs not in (None, UNKNOWN, [], ()): out(' '*6+'\\textbf{Raises}\n') out(' \\vspace{-1ex}\n\n') out(' '*6+'\\begin{quote}\n') out(' \\begin{description}\n\n') for name, descr in func_doc.exception_descrs: out(' '*10+'\\item[\\texttt{%s}]\n\n' % plaintext_to_latex('%s' % name)) out(self.docstring_to_latex(descr, 10)) out(' \\end{description}\n\n') out(' '*6+'\\end{quote}\n\n') ## Overrides if var_doc.overrides not in (None, UNKNOWN): out(' Overrides: ' + plaintext_to_latex('%s'%var_doc.overrides.canonical_name)) if (func_doc.docstring in (None, UNKNOWN) and var_doc.overrides.value.docstring not in (None, UNKNOWN)): out(' \textit{(inherited documentation)}') out('\n\n') # Add version, author, warnings, requirements, notes, etc. self.write_standard_fields(out, func_doc) out(' \\end{boxedminipage}\n\n') def function_signature(self, var_doc): func_doc = var_doc.value func_name = var_doc.name # This should never happen, but just in case: if func_doc in (None, UNKNOWN): return ('\\raggedright \\textbf{%s}(...)' % plaintext_to_latex(func_name)) if func_doc.posargs == UNKNOWN: args = ['...'] else: args = [self.func_arg(name, default) for (name, default) in zip(func_doc.posargs, func_doc.posarg_defaults)] if func_doc.vararg: if func_doc.vararg == '...': args.append('\\textit{...}') else: args.append('*\\textit{%s}' % plaintext_to_latex(func_doc.vararg)) if func_doc.kwarg: args.append('**\\textit{%s}' % plaintext_to_latex(func_doc.kwarg)) return ('\\raggedright \\textbf{%s}(%s)' % (plaintext_to_latex(func_name), ', '.join(args))) def func_arg(self, name, default): s = '\\textit{%s}' % plaintext_to_latex(self._arg_name(name)) if default is not None: s += '={\\tt %s}' % default.summary_pyval_repr().to_latex(None) return s def _arg_name(self, arg): if isinstance(arg, basestring): return arg elif len(arg) == 1: return '(%s,)' % self._arg_name(arg[0]) else: return '(%s)' % (', '.join([self._arg_name(a) for a in arg])) #//////////////////////////////////////////////////////////// #{ Variable List #//////////////////////////////////////////////////////////// _VAR_GROUP_HEADER = '\\multicolumn{2}{|l|}{\\textit{%s}}\\\\\n' # Also used for the property list. def write_var_list(self, out, heading, doc, value_type, seclevel=1): groups = [(plaintext_to_latex(group_name), doc.select_variables(group=group_name, imported=False, value_type=value_type, public=self._public_filter)) for group_name in doc.group_names()] # Discard any empty groups; and return if they're all empty. groups = [(g,vars) for (g,vars) in groups if vars] if not groups: return # Write a header. self.write_start_of(out, heading) out(' '+self.section(heading, seclevel)) # [xx] without this, there's a huge gap before the table -- why?? out(' \\vspace{-1cm}\n') out('\\hspace{\\varindent}') out('\\begin{longtable}') out('{|p{\\varnamewidth}|') out('p{\\vardescrwidth}|l}\n') out('\\cline{1-2}\n') # Set up the headers & footer (this makes the table span # multiple pages in a happy way). out('\\cline{1-2} ') out('\\centering \\textbf{Name} & ') out('\\centering \\textbf{Description}& \\\\\n') out('\\cline{1-2}\n') out('\\endhead') out('\\cline{1-2}') out('\\multicolumn{3}{r}{\\small\\textit{') out('continued on next page}}\\\\') out('\\endfoot') out('\\cline{1-2}\n') out('\\endlastfoot') # Write a section for each group. grouped_inh_vars = {} for name, var_docs in groups: self.write_var_group(out, doc, name, var_docs, grouped_inh_vars) # Write a section for each inheritance pseudo-group (used if # inheritance=='grouped') if grouped_inh_vars: for base in doc.mro(): if base in grouped_inh_vars: hdr = ('Inherited from %s' % plaintext_to_latex('%s' % base.canonical_name)) if self._crossref and base in self.class_set: hdr += (' \\textit{(Section \\ref{%s})}' % self.label(base)) out(self._VAR_GROUP_HEADER % (hdr)) out('\\cline{1-2}\n') for var_doc in grouped_inh_vars[base]: if isinstance(var_doc.value3, PropertyDoc): self.write_property_list_line(out, var_doc) else: self.write_var_list_line(out, var_doc) out('\\end{longtable}\n\n') def write_var_group(self, out, doc, name, var_docs, grouped_inh_vars): # Split up the var_docs list, according to the way each var # should be displayed: # - listed_inh_vars -- for listed inherited variables. # - grouped_inh_vars -- for grouped inherited variables. # - normal_vars -- for all other variables. listed_inh_vars = {} normal_vars = [] for var_doc in var_docs: if var_doc.container != doc: base = var_doc.container if (base not in self.class_set or self._inheritance == 'listed'): listed_inh_vars.setdefault(base,[]).append(var_doc) elif self._inheritance == 'grouped': grouped_inh_vars.setdefault(base,[]).append(var_doc) else: normal_vars.append(var_doc) else: normal_vars.append(var_doc) # Write a header for the group. if name: out(self._VAR_GROUP_HEADER % name) out('\\cline{1-2}\n') # Write an entry for each normal var: for var_doc in normal_vars: if isinstance(var_doc.value, PropertyDoc): self.write_property_list_line(out, var_doc) else: self.write_var_list_line(out, var_doc) # Write a subsection for inherited vars: if listed_inh_vars: self.write_var_inheritance_list(out, doc, listed_inh_vars) def write_var_inheritance_list(self, out, doc, listed_inh_vars): for base in doc.mro(): if base not in listed_inh_vars: continue #if str(base.canonical_name) == 'object': continue var_docs = listed_inh_vars[base] if self._public_filter: var_docs = [v for v in var_docs if v.is_public] if var_docs: hdr = ('Inherited from %s' % plaintext_to_latex('%s' % base.canonical_name)) if self._crossref and base in self.class_set: hdr += (' \\textit{(Section \\ref{%s})}' % self.label(base)) out(self._VAR_GROUP_HEADER % hdr) out('\\multicolumn{2}{|p{\\varwidth}|}{' '\\raggedright %s}\\\\\n' % ', '.join(['%s' % plaintext_to_latex(var_doc.name) for var_doc in var_docs])) out('\\cline{1-2}\n') def write_var_list_line(self, out, var_doc): out('\\raggedright ') out(plaintext_to_latex(var_doc.name, nbsp=True, breakany=True)) out(' & ') has_descr = var_doc.descr not in (None, UNKNOWN) has_type = var_doc.type_descr not in (None, UNKNOWN) has_value = var_doc.value is not UNKNOWN if has_type or has_value: out('\\raggedright ') if has_descr: out(self.docstring_to_latex(var_doc.descr, 10).strip()) if has_type or has_value: out('\n\n') if has_value: out('\\textbf{Value:} \n{\\tt %s}' % var_doc.value.summary_pyval_repr().to_latex(None)) if has_type: ptype = self.docstring_to_latex(var_doc.type_descr, 12).strip() out('%s{\\it (type=%s)}' % (' '*12, ptype)) out('&\\\\\n') out('\\cline{1-2}\n') def write_property_list_line(self, out, var_doc): prop_doc = var_doc.value out('\\raggedright ') out(plaintext_to_latex(var_doc.name, nbsp=True, breakany=True)) out(' & ') has_descr = prop_doc.descr not in (None, UNKNOWN) has_type = prop_doc.type_descr not in (None, UNKNOWN) if has_descr or has_type: out('\\raggedright ') if has_descr: out(self.docstring_to_latex(prop_doc.descr, 10).strip()) if has_type: out('\n\n') if has_type: ptype = self.docstring_to_latex(prop_doc.type_descr, 12).strip() out('%s{\\it (type=%s)}' % (' '*12, ptype)) # [xx] List the fget/fset/fdel functions? out('&\\\\\n') out('\\cline{1-2}\n') #//////////////////////////////////////////////////////////// #{ Standard Fields #//////////////////////////////////////////////////////////// # Copied from HTMLWriter: def write_standard_fields(self, out, doc): fields = [] field_values = {} #if _sort_fields: fields = STANDARD_FIELD_NAMES [XX] for (field, arg, descr) in doc.metadata: if field not in field_values: fields.append(field) if field.takes_arg: subfields = field_values.setdefault(field,{}) subfields.setdefault(arg,[]).append(descr) else: field_values.setdefault(field,[]).append(descr) for field in fields: if field.takes_arg: for arg, descrs in field_values[field].items(): self.write_standard_field(out, doc, field, descrs, arg) else: self.write_standard_field(out, doc, field, field_values[field]) def write_standard_field(self, out, doc, field, descrs, arg=''): singular = field.singular plural = field.plural if arg: singular += ' (%s)' % arg plural += ' (%s)' % arg out(self._descrlist([self.docstring_to_latex(d) for d in descrs], field.singular, field.plural, field.short)) def _descrlist(self, items, singular, plural=None, short=0): if plural is None: plural = singular if len(items) == 0: return '' if len(items) == 1 and singular is not None: return '\\textbf{%s:} %s\n\n' % (singular, items[0]) if short: s = '\\textbf{%s:}\n' % plural items = [item.strip() for item in items] return s + ',\n '.join(items) + '\n\n' else: s = '\\textbf{%s:}\n' % plural s += '\\begin{quote}\n' s += ' \\begin{itemize}\n\n \item\n' s += ' \\setlength{\\parskip}{0.6ex}\n' s += '\n\n \item '.join(items) return s + '\n\n\\end{itemize}\n\n\\end{quote}\n\n' #//////////////////////////////////////////////////////////// #{ Docstring -> LaTeX Conversion #//////////////////////////////////////////////////////////// # We only need one linker, since we don't use context: class _LatexDocstringLinker(markup.DocstringLinker): def translate_indexterm(self, indexterm): indexstr = re.sub(r'["!|@]', r'"\1', indexterm.to_latex(self)) return ('\\index{%s}\\textit{%s}' % (indexstr, indexstr)) def translate_identifier_xref(self, identifier, label=None): if label is None: label = markup.plaintext_to_latex(identifier) return '\\texttt{%s}' % label _docstring_linker = _LatexDocstringLinker() def docstring_to_latex(self, docstring, indent=0, breakany=0): if docstring is None: return '' return docstring.to_latex(self._docstring_linker, indent=indent, hyperref=self._hyperref) #//////////////////////////////////////////////////////////// #{ Helpers #//////////////////////////////////////////////////////////// def write_header(self, out, where): out('%\n% API Documentation') if self._prj_name: out(' for %s' % self._prj_name) if isinstance(where, APIDoc): out('\n%% %s %s' % (self.doc_kind(where), where.canonical_name)) else: out('\n%% %s' % where) out('\n%%\n%% Generated by epydoc %s\n' % epydoc.__version__) out('%% [%s]\n%%\n' % time.asctime(time.localtime(time.time()))) def write_start_of(self, out, section_name): out('\n' + 75*'%' + '\n') out('%%' + ((71-len(section_name))/2)*' ') out(section_name) out(((72-len(section_name))/2)*' ' + '%%\n') out(75*'%' + '\n\n') def section(self, title, depth=0): sec = self.SECTIONS[depth+self._top_section] return (('%s\n\n' % sec) % plaintext_to_latex(title)) def sectionstar(self, title, depth): sec = self.STARSECTIONS[depth+self._top_section] return (('%s\n\n' % sec) % plaintext_to_latex(title)) def doc_kind(self, doc): if isinstance(doc, ModuleDoc) and doc.is_package == True: return 'Package' elif (isinstance(doc, ModuleDoc) and doc.canonical_name[0].startswith('script')): return 'Script' elif isinstance(doc, ModuleDoc): return 'Module' elif isinstance(doc, ClassDoc): return 'Class' elif isinstance(doc, ClassMethodDoc): return 'Class Method' elif isinstance(doc, StaticMethodDoc): return 'Static Method' elif isinstance(doc, RoutineDoc): if isinstance(self.docindex.container(doc), ClassDoc): return 'Method' else: return 'Function' else: return 'Variable' def indexterm(self, doc, pos='only'): """Mark a term or section for inclusion in the index.""" if not self._index: return '' if isinstance(doc, RoutineDoc) and not self._index_functions: return '' pieces = [] while doc is not None: if doc.canonical_name == UNKNOWN: return '' # Give up. pieces.append('%s \\textit{(%s)}' % (plaintext_to_latex('%s'%doc.canonical_name), self.doc_kind(doc).lower())) doc = self.docindex.container(doc) if doc == UNKNOWN: return '' # Give up. pieces.reverse() if pos == 'only': return '\\index{%s}\n' % '!'.join(pieces) elif pos == 'start': return '\\index{%s|(}\n' % '!'.join(pieces) elif pos == 'end': return '\\index{%s|)}\n' % '!'.join(pieces) else: raise AssertionError('Bad index position %s' % pos) def label(self, doc): return ':'.join(doc.canonical_name) #: Map the Python encoding representation into mismatching LaTeX ones. latex_encodings = { 'utf-8': 'utf8', } def get_latex_encoding(self): """ @return: The LaTeX representation of the selected encoding. @rtype: C{str} """ enc = self._encoding.lower() return self.latex_encodings.get(enc, enc) epydoc-3.0.1+dfsg/epydoc/docwriter/__init__.py0000644000175000017500000000037410654406440021602 0ustar pronovicpronovic# epydoc -- Output generation # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: __init__.py 956 2006-03-10 01:30:51Z edloper $ """ Output generation. """ __docformat__ = 'epytext en' epydoc-3.0.1+dfsg/epydoc/docwriter/html_css.py0000644000175000017500000006065410676012376021673 0ustar pronovicpronovic# # epydoc.css: default epydoc CSS stylesheets # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: html_css.py 1634 2007-09-24 15:58:38Z dvarrazzo $ # """ Predefined CSS stylesheets for the HTML outputter (L{epydoc.docwriter.html}). @type STYLESHEETS: C{dictionary} from C{string} to C{(string, string)} @var STYLESHEETS: A dictionary mapping from stylesheet names to CSS stylesheets and descriptions. A single stylesheet may have multiple names. Currently, the following stylesheets are defined: - C{default}: The default stylesheet (synonym for C{white}). - C{white}: Black on white, with blue highlights (similar to javadoc). - C{blue}: Black on steel blue. - C{green}: Black on green. - C{black}: White on black, with blue highlights - C{grayscale}: Grayscale black on white. - C{none}: An empty stylesheet. """ __docformat__ = 'epytext en' import re ############################################################ ## Basic stylesheets ############################################################ # [xx] Should I do something like: # # @import url(html4css1.css); # # But then where do I get that css file from? Hm. # Also, in principle I'm mangling classes, but it looks like I'm # failing. # # Black on white, with blue highlights. This is similar to how # javadoc looks. TEMPLATE = """ /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: $body_bg; color: $body_fg; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: $body_link; } a:visited { color: $body_visited_link; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: $navbar_bg; color: $navbar_fg; border: $navbar_border; } table.navbar table { color: $navbar_fg; } th.navbar-select { background: $navbar_select_bg; color: $navbar_select_fg; } table.navbar a { text-decoration: none; } table.navbar a:link { color: $navbar_link; } table.navbar a:visited { color: $navbar_visited_link; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: $table_hdr_bg; color: $table_hdr_fg; border: $table_border; } td.table-header table { color: $table_hdr_fg; } td.table-header table a:link { color: $table_hdr_link; } td.table-header table a:visited { color: $table_hdr_visited_link; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: $group_hdr_bg; color: $group_hdr_fg; text-align: left; font-style: italic; font-size: 115%; border: $table_border; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin-bottom: 0.5em; } td.summary { border: $table_border; } code.summary-type { font-size: 85%; } table.summary a:link { color: $table_link; } table.summary a:visited { color: $table_visited_link; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin: .2em 0 0 0; } table.details table { color: $table_fg; } table.details a:link { color: $table_link; } table.details a:visited { color: $table_visited_link; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; } td.link-index { border-width: 0px; } table.link-index a:link { color: $table_link; } table.link-index a:visited { color: $table_visited_link; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: $table_bg; color: $table_fg; border: $table_border; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: $table_link; } table.metadata-index a:visited { color: $table_visited_link; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: $sig_name; } .sig-arg { color: $sig_arg; } .sig-default { color: $sig_default; } .summary-sig { font-family: monospace; } .summary-sig-name { color: $summary_sig_name; font-weight: bold; } table.summary a.summary-sig-name:link { color: $summary_sig_name; font-weight: bold; } table.summary a.summary-sig-name:visited { color: $summary_sig_name; font-weight: bold; } .summary-sig-arg { color: $summary_sig_arg; } .summary-sig-default { color: $summary_sig_default; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: $summary_sig_name; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: $summary_sig_name; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: $summary_sig_name; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: $variable_bg; color: $variable_fg; border: $variable_border; } .variable-linewrap { color: $variable_linewrap; font-weight: bold; } .variable-ellipsis { color: $variable_ellipsis; font-weight: bold; } .variable-quote { color: $variable_quote; font-weight: bold; } .variable-group { color: $variable_group; font-weight: bold; } .variable-op { color: $variable_op; font-weight: bold; } .variable-string { color: $variable_string; } .variable-unknown { color: $variable_unknown; font-weight: bold; } .re { color: $re; } .re-char { color: $re_char; } .re-op { color: $re_op; } .re-group { color: $re_group; } .re-ref { color: $re_ref; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: $doctest_bg; color: $doctest_fg; border: $doctest_border; } table pre.py-doctest { background: $doctest_in_table_bg; color: $doctest_in_table_fg; } pre.py-src { border: $pysrc_border; background: $pysrc_bg; color: $pysrc_fg; } .py-line { border-left: $pysrc_sep_border; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: $pysrc_border; border-bottom: $pysrc_border; background: $pysrc_highlight_hdr_bg; } div.py-highlight { border-bottom: $pysrc_border; background: $pysrc_highlight_bg; } .py-prompt { color: $py_prompt; font-weight: bold;} .py-more { color: $py_more; font-weight: bold;} .py-string { color: $py_string; } .py-comment { color: $py_comment; } .py-keyword { color: $py_keyword; } .py-output { color: $py_output; } .py-name { color: $py_name; } .py-name:link { color: $py_name !important; } .py-name:visited { color: $py_name !important; } .py-number { color: $py_number; } .py-defname { color: $py_def_name; font-weight: bold; } .py-def-name { color: $py_def_name; font-weight: bold; } .py-base-class { color: $py_base_class; } .py-param { color: $py_param; } .py-docstring { color: $py_docstring; } .py-decorator { color: $py_decorator; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: $graph_border; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: $log_bg; color: $log_fg; border: $log_border; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: $log_error_bg; color: $log_error_fg; border: $log_error_border; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: $log_warn_bg; color: $log_warn_fg; border: $log_warn_border; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: $log_info_bg; color: $log_info_fg; border: $log_info_border; } h2.log-hdr { background: $log_hdr_bg; color: $log_hdr_fg; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: $log_border; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: $opt_changed_fg; font-weight: bold; } tr.opt-default { color: $opt_default_fg; } pre.log { margin: 0; padding: 0; padding-left: 1em; } """ ############################################################ ## Derived stylesheets ############################################################ # Use some simple manipulations to produce a wide variety of color # schemes. In particular, use th _COLOR_RE regular expression to # search for colors, and to transform them in various ways. _COLOR_RE = re.compile(r'#(..)(..)(..)') def _set_colors(template, *dicts): colors = dicts[0].copy() for d in dicts[1:]: colors.update(d) return re.sub(r'\$(\w+)', lambda m:colors[m.group(1)], template) def _rv(match): """ Given a regexp match for a color, return the reverse-video version of that color. @param match: A regular expression match. @type match: C{Match} @return: The reverse-video color. @rtype: C{string} """ rgb = [int(grp, 16) for grp in match.groups()] return '#' + ''.join(['%02x' % (255-c) for c in rgb]) def _darken_darks(match): rgb = [int(grp, 16) for grp in match.groups()] return '#' + ''.join(['%02x' % (((c/255.)**2) * 255) for c in rgb]) _WHITE_COLORS = dict( # Defaults: body_bg = '#ffffff', body_fg = '#000000', body_link = '#0000ff', body_visited_link = '#204080', # Navigation bar: navbar_bg = '#a0c0ff', navbar_fg = '#000000', navbar_border = '2px groove #c0d0d0', navbar_select_bg = '#70b0ff', navbar_select_fg = '#000000', navbar_link = '#0000ff', navbar_visited_link = '#204080', # Tables (summary tables, details tables, indices): table_bg = '#e8f0f8', table_fg = '#000000', table_link = '#0000ff', table_visited_link = '#204080', table_border = '1px solid #608090', table_hdr_bg = '#70b0ff', table_hdr_fg = '#000000', table_hdr_link = '#0000ff', table_hdr_visited_link = '#204080', group_hdr_bg = '#c0e0f8', group_hdr_fg = '#000000', # Function signatures: sig_name = '#006080', sig_arg = '#008060', sig_default = '#602000', summary_sig_name = '#006080', summary_sig_arg = '#006040', summary_sig_default = '#501800', # Variable values: variable_bg = '#dce4ec', variable_fg = '#000000', variable_border = '1px solid #708890', variable_linewrap = '#604000', variable_ellipsis = '#604000', variable_quote = '#604000', variable_group = '#008000', variable_string = '#006030', variable_op = '#604000', variable_unknown = '#a00000', re = '#000000', re_char = '#006030', re_op = '#600000', re_group = '#003060', re_ref = '#404040', # Python source code: doctest_bg = '#e8f0f8', doctest_fg = '#000000', doctest_border = '1px solid #708890', doctest_in_table_bg = '#dce4ec', doctest_in_table_fg = '#000000', pysrc_border = '2px solid #000000', pysrc_sep_border = '2px solid #000000', pysrc_bg = '#f0f0f0', pysrc_fg = '#000000', pysrc_highlight_hdr_bg = '#d8e8e8', pysrc_highlight_bg = '#d0e0e0', py_prompt = '#005050', py_more = '#005050', py_string = '#006030', py_comment = '#003060', py_keyword = '#600000', py_output = '#404040', py_name = '#000050', py_number = '#005000', py_def_name = '#000060', py_base_class = '#000060', py_param = '#000060', py_docstring = '#006030', py_decorator = '#804020', # Graphs graph_border = '1px solid #000000', # Log block log_bg = '#e8f0f8', log_fg = '#000000', log_border = '1px solid #000000', log_hdr_bg = '#70b0ff', log_hdr_fg = '#000000', log_error_bg = '#ffb0b0', log_error_fg = '#000000', log_error_border = '1px solid #000000', log_warn_bg = '#ffffb0', log_warn_fg = '#000000', log_warn_border = '1px solid #000000', log_info_bg = '#b0ffb0', log_info_fg = '#000000', log_info_border = '1px solid #000000', opt_changed_fg = '#000000', opt_default_fg = '#606060', ) _BLUE_COLORS = _WHITE_COLORS.copy() _BLUE_COLORS.update(dict( # Body: white text on a dark blue background body_bg = '#000070', body_fg = '#ffffff', body_link = '#ffffff', body_visited_link = '#d0d0ff', # Tables: cyan headers, black on white bodies table_bg = '#ffffff', table_fg = '#000000', table_hdr_bg = '#70b0ff', table_hdr_fg = '#000000', table_hdr_link = '#000000', table_hdr_visited_link = '#000000', table_border = '1px solid #000000', # Navigation bar: blue w/ cyan selection navbar_bg = '#0000ff', navbar_fg = '#ffffff', navbar_link = '#ffffff', navbar_visited_link = '#ffffff', navbar_select_bg = '#70b0ff', navbar_select_fg = '#000000', navbar_border = '1px solid #70b0ff', # Variable values & doctest blocks: cyan variable_bg = '#c0e0f8', variable_fg = '#000000', doctest_bg = '#c0e0f8', doctest_fg = '#000000', doctest_in_table_bg = '#c0e0f8', doctest_in_table_fg = '#000000', )) _WHITE = _set_colors(TEMPLATE, _WHITE_COLORS) _BLUE = _set_colors(TEMPLATE, _BLUE_COLORS) # Black-on-green _GREEN = _COLOR_RE.sub(_darken_darks, _COLOR_RE.sub(r'#\1\3\2', _BLUE)) # White-on-black, with blue highlights. _BLACK = _COLOR_RE.sub(r'#\3\2\1', _COLOR_RE.sub(_rv, _WHITE)) # Grayscale _GRAYSCALE = _COLOR_RE.sub(r'#\2\2\2', _WHITE) ############################################################ ## Stylesheet table ############################################################ STYLESHEETS = { 'white': (_WHITE, "Black on white, with blue highlights"), 'blue': (_BLUE, "Black on steel blue"), 'green': (_GREEN, "Black on green"), 'black': (_BLACK, "White on black, with blue highlights"), 'grayscale': (_GRAYSCALE, "Grayscale black on white"), 'default': (_WHITE, "Default stylesheet (=white)"), # 'none': (_LAYOUT, "A base stylesheet (no color modifications)"), } epydoc-3.0.1+dfsg/epydoc/docwriter/plaintext.py0000644000175000017500000002507210654406440022055 0ustar pronovicpronovic# epydoc -- Plaintext output generation # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: plaintext.py 1473 2007-02-13 19:46:05Z edloper $ """ Plaintext output generation. """ __docformat__ = 'epytext en' from epydoc.apidoc import * import re class PlaintextWriter: def write(self, api_doc, **options): result = [] out = result.append self._cols = options.get('cols', 75) try: if isinstance(api_doc, ModuleDoc): self.write_module(out, api_doc) elif isinstance(api_doc, ClassDoc): self.write_class(out, api_doc) elif isinstance(api_doc, RoutineDoc): self.write_function(out, api_doc) else: assert 0, ('%s not handled yet' % api_doc.__class__) except Exception, e: print '\n\n' print ''.join(result) raise return ''.join(result) def write_module(self, out, mod_doc): #for n,v in mod_doc.variables.items(): # print n, `v.value`, `v.value.value` # The cannonical name of the module. out(self.section('Module Name')) out(' %s\n\n' % mod_doc.canonical_name) # The module's description. if mod_doc.descr not in (None, '', UNKNOWN): out(self.section('Description')) out(mod_doc.descr.to_plaintext(None, indent=4)) #out('metadata: %s\n\n' % mod_doc.metadata) # [xx] testing self.write_list(out, 'Classes', mod_doc, value_type='class') self.write_list(out, 'Functions', mod_doc, value_type='function') self.write_list(out, 'Variables', mod_doc, value_type='other') # hmm.. do this as just a flat list?? #self.write_list(out, 'Imports', mod_doc, imported=True, verbose=False) def baselist(self, class_doc): if class_doc.bases is UNKNOWN: return '(unknown bases)' if len(class_doc.bases) == 0: return '' s = '(' class_parent = class_doc.canonical_name.container() for i, base in enumerate(class_doc.bases): if base.canonical_name is None: if base.parse_repr is not UNKNOWN: s += base.parse_repr else: s += '??' elif base.canonical_name.container() == class_parent: s += str(base.canonical_name[-1]) else: s += str(base.canonical_name) if i < len(class_doc.bases)-1: out(', ') return s+')' def write_class(self, out, class_doc, name=None, prefix='', verbose=True): baselist = self.baselist(class_doc) # If we're at the top level, then list the cannonical name of # the class; otherwise, our parent will have already printed # the name of the variable containing the class. if prefix == '': out(self.section('Class Name')) out(' %s%s\n\n' % (class_doc.canonical_name, baselist)) else: out(prefix + 'class %s' % self.bold(str(name)) + baselist+'\n') if not verbose: return # Indent the body if prefix != '': prefix += ' | ' # The class's description. if class_doc.descr not in (None, '', UNKNOWN): if prefix == '': out(self.section('Description', prefix)) out(self._descr(class_doc.descr, ' ')) else: out(self._descr(class_doc.descr, prefix)) # List of nested classes in this class. self.write_list(out, 'Methods', class_doc, value_type='instancemethod', prefix=prefix, noindent=len(prefix)>4) self.write_list(out, 'Class Methods', class_doc, value_type='classmethod', prefix=prefix) self.write_list(out, 'Static Methods', class_doc, value_type='staticmethod', prefix=prefix) self.write_list(out, 'Nested Classes', class_doc, value_type='class', prefix=prefix) self.write_list(out, 'Instance Variables', class_doc, value_type='instancevariable', prefix=prefix) self.write_list(out, 'Class Variables', class_doc, value_type='classvariable', prefix=prefix) self.write_list(out, 'Inherited Methods', class_doc, value_type='method', prefix=prefix, inherited=True, verbose=False) self.write_list(out, 'Inherited Instance Variables', class_doc, value_type='instancevariable', prefix=prefix, inherited=True, verbose=False) self.write_list(out, 'Inherited Class Variables', class_doc, value_type='classvariable', prefix=prefix, inherited=True, verbose=False) self.write_list(out, 'Inherited Nested Classes', class_doc, value_type='class', prefix=prefix, inherited=True, verbose=False) def write_variable(self, out, var_doc, name=None, prefix='', verbose=True): if name is None: name = var_doc.name out(prefix+self.bold(str(name))) if (var_doc.value not in (UNKNOWN, None) and var_doc.is_alias is True and var_doc.value.canonical_name not in (None, UNKNOWN)): out(' = %s' % var_doc.value.canonical_name) elif var_doc.value not in (UNKNOWN, None): val_repr = var_doc.value.summary_pyval_repr( max_len=self._cols-len(name)-len(prefix)-3) out(' = %s' % val_repr.to_plaintext(None)) out('\n') if not verbose: return prefix += ' ' # indent the body. if var_doc.descr not in (None, '', UNKNOWN): out(self._descr(var_doc.descr, prefix)) def write_property(self, out, prop_doc, name=None, prefix='', verbose=True): if name is None: name = prop_doc.canonical_name out(prefix+self.bold(str(name))) if not verbose: return prefix += ' ' # indent the body. if prop_doc.descr not in (None, '', UNKNOWN): out(self._descr(prop_doc.descr, prefix)) def write_function(self, out, func_doc, name=None, prefix='', verbose=True): if name is None: name = func_doc.canonical_name self.write_signature(out, func_doc, name, prefix) if not verbose: return prefix += ' ' # indent the body. if func_doc.descr not in (None, '', UNKNOWN): out(self._descr(func_doc.descr, prefix)) if func_doc.return_descr not in (None, '', UNKNOWN): out(self.section('Returns:', prefix)) out(self._descr(func_doc.return_descr, prefix+' ')) if func_doc.return_type not in (None, '', UNKNOWN): out(self.section('Return Type:', prefix)) out(self._descr(func_doc.return_type, prefix+' ')) def write_signature(self, out, func_doc, name, prefix): args = [self.fmt_arg(argname, default) for (argname, default) in zip(func_doc.posargs, func_doc.posarg_defaults)] if func_doc.vararg: args.append('*'+func_doc.vararg) if func_doc.kwarg: args.append('**'+func_doc.kwarg) out(prefix+self.bold(str(name))+'(') x = left = len(prefix) + len(name) + 1 for i, arg in enumerate(args): if x > left and x+len(arg) > 75: out('\n'+prefix + ' '*len(name) + ' ') x = left out(arg) x += len(arg) if i < len(args)-1: out(', ') x += 2 out(')\n') # [xx] tuple args! def fmt_arg(self, name, default): if default is None: return '%s' % name else: default_repr = default.summary_pyval_repr() return '%s=%s' % (name, default_repr.to_plaintext(None)) def write_list(self, out, heading, doc, value_type=None, imported=False, inherited=False, prefix='', noindent=False, verbose=True): # Get a list of the VarDocs we should describe. if isinstance(doc, ClassDoc): var_docs = doc.select_variables(value_type=value_type, imported=imported, inherited=inherited) else: var_docs = doc.select_variables(value_type=value_type, imported=imported) if not var_docs: return out(prefix+'\n') if not noindent: out(self.section(heading, prefix)) prefix += ' ' for i, var_doc in enumerate(var_docs): val_doc, name = var_doc.value, var_doc.name if verbose: out(prefix+'\n') # hmm: if not verbose: if isinstance(doc, ClassDoc): name = var_doc.canonical_name elif val_doc not in (None, UNKNOWN): name = val_doc.canonical_name if isinstance(val_doc, RoutineDoc): self.write_function(out, val_doc, name, prefix, verbose) elif isinstance(val_doc, PropertyDoc): self.write_property(out, val_doc, name, prefix, verbose) elif isinstance(val_doc, ClassDoc): self.write_class(out, val_doc, name, prefix, verbose) else: self.write_variable(out, var_doc, name, prefix, verbose) def _descr(self, descr, prefix): s = descr.to_plaintext(None, indent=len(prefix)).rstrip() s = '\n'.join([(prefix+l[len(prefix):]) for l in s.split('\n')]) return s+'\n'#+prefix+'\n' # def drawline(self, s, x): # s = re.sub(r'(?m)^(.{%s}) ' % x, r'\1|', s) # return re.sub(r'(?m)^( {,%s})$(?=\n)' % x, x*' '+'|', s) #//////////////////////////////////////////////////////////// # Helpers #//////////////////////////////////////////////////////////// def bold(self, text): """Write a string in bold by overstriking.""" return ''.join([ch+'\b'+ch for ch in text]) def title(self, text, indent): return ' '*indent + self.bold(text.capitalize()) + '\n\n' def section(self, text, indent=''): if indent == '': return indent + self.bold(text.upper()) + '\n' else: return indent + self.bold(text.capitalize()) + '\n' epydoc-3.0.1+dfsg/epydoc/docwriter/html.py0000644000175000017500000043110210747617530021013 0ustar pronovicpronovic# # epydoc -- HTML output generator # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: html.py 1674 2008-01-29 06:03:36Z edloper $ # """ The HTML output generator for epydoc. The main interface provided by this module is the L{HTMLWriter} class. @todo: Add a cache to L{HTMLWriter.url()}? """ __docformat__ = 'epytext en' import re, os, sys, codecs, sre_constants, pprint, base64 import urllib import __builtin__ from epydoc.apidoc import * import epydoc.docstringparser import time, epydoc, epydoc.markup, epydoc.markup.epytext from epydoc.docwriter.html_colorize import PythonSourceColorizer from epydoc.docwriter import html_colorize from epydoc.docwriter.html_css import STYLESHEETS from epydoc.docwriter.html_help import HTML_HELP from epydoc.docwriter.dotgraph import * from epydoc import log from epydoc.util import plaintext_to_html, is_src_filename from epydoc.compat import * # Backwards compatibility ###################################################################### ## Template Compiler ###################################################################### # The compile_template() method defined in this section is used to # define several of HTMLWriter's methods. def compile_template(docstring, template_string, output_function='out', debug=epydoc.DEBUG): """ Given a template string containing inline python source code, return a python function that will fill in the template, and output the result. The signature for this function is taken from the first line of C{docstring}. Output is generated by making repeated calls to the output function with the given name (which is typically one of the function's parameters). The templating language used by this function passes through all text as-is, with three exceptions: - If every line in the template string is indented by at least M{x} spaces, then the first M{x} spaces are stripped from each line. - Any line that begins with '>>>' (with no indentation) should contain python code, and will be inserted as-is into the template-filling function. If the line begins a control block (such as 'if' or 'for'), then the control block will be closed by the first '>>>'-marked line whose indentation is less than or equal to the line's own indentation (including lines that only contain comments.) - In any other line, any expression between two '$' signs will be evaluated and inserted into the line (using C{str()} to convert the result to a string). Here is a simple example: >>> TEMPLATE = ''' ... ... $book.title$ ... $book.count_pages()$ ... >>> for chapter in book.chapters: ... $chapter.name$ ... >>> #endfor ... >>> write_book = compile_template('write_book(out, book)', TEMPLATE) @newfield acknowledgements: Acknowledgements @acknowledgements: The syntax used by C{compile_template} is loosely based on Cheetah. """ # Extract signature from the docstring: signature = docstring.lstrip().split('\n',1)[0].strip() func_name = signature.split('(',1)[0].strip() # Regexp to search for inline substitutions: INLINE = re.compile(r'\$([^\$]+)\$') # Regexp to search for python statements in the template: COMMAND = re.compile(r'(^>>>.*)\n?', re.MULTILINE) # Strip indentation from the template. template_string = strip_indent(template_string) # If we're debugging, then we'll store the generated function, # so we can print it along with any tracebacks that depend on it. if debug: signature = re.sub(r'\)\s*$', ', __debug=__debug)', signature) # Funciton declaration line pysrc_lines = ['def %s:' % signature] indents = [-1] if debug: pysrc_lines.append(' try:') indents.append(-1) commands = COMMAND.split(template_string.strip()+'\n') for i, command in enumerate(commands): if command == '': continue # String literal segment: if i%2 == 0: pieces = INLINE.split(command) for j, piece in enumerate(pieces): if j%2 == 0: # String piece pysrc_lines.append(' '*len(indents)+ '%s(%r)' % (output_function, piece)) else: # Variable piece pysrc_lines.append(' '*len(indents)+ '%s(unicode(%s))' % (output_function, piece)) # Python command: else: srcline = command[3:].lstrip() # Update indentation indent = len(command)-len(srcline) while indent <= indents[-1]: indents.pop() # Add on the line. srcline = srcline.rstrip() pysrc_lines.append(' '*len(indents)+srcline) if srcline.endswith(':'): indents.append(indent) if debug: pysrc_lines.append(' except Exception,e:') pysrc_lines.append(' pysrc, func_name = __debug ') pysrc_lines.append(' lineno = sys.exc_info()[2].tb_lineno') pysrc_lines.append(' print ("Exception in template %s() on "') pysrc_lines.append(' "line %d:" % (func_name, lineno))') pysrc_lines.append(' print pysrc[lineno-1]') pysrc_lines.append(' raise') pysrc = '\n'.join(pysrc_lines)+'\n' #log.debug(pysrc) if debug: localdict = {'__debug': (pysrc_lines, func_name)} else: localdict = {} try: exec pysrc in globals(), localdict except SyntaxError: log.error('Error in script:\n' + pysrc + '\n') raise template_func = localdict[func_name] template_func.__doc__ = docstring return template_func def strip_indent(s): """ Given a multiline string C{s}, find the minimum indentation for all non-blank lines, and return a new string formed by stripping that amount of indentation from all lines in C{s}. """ # Strip indentation from the template. minindent = sys.maxint lines = s.split('\n') for line in lines: stripline = line.lstrip() if stripline: minindent = min(minindent, len(line)-len(stripline)) return '\n'.join([l[minindent:] for l in lines]) ###################################################################### ## HTML Writer ###################################################################### class HTMLWriter: #//////////////////////////////////////////////////////////// # Table of Contents #//////////////////////////////////////////////////////////// # # 1. Interface Methods # # 2. Page Generation -- write complete web page files # 2.1. Module Pages # 2.2. Class Pages # 2.3. Trees Page # 2.4. Indices Page # 2.5. Help Page # 2.6. Frames-based table of contents pages # 2.7. Homepage (index.html) # 2.8. CSS Stylesheet # 2.9. Javascript file # 2.10. Graphs # 2.11. Images # # 3. Page Element Generation -- write pieces of a web page file # 3.1. Page Header # 3.2. Page Footer # 3.3. Navigation Bar # 3.4. Breadcrumbs # 3.5. Summary Tables # # 4. Helper functions def __init__(self, docindex, **kwargs): """ Construct a new HTML writer, using the given documentation index. @param docindex: The documentation index. @type prj_name: C{string} @keyword prj_name: The name of the project. Defaults to none. @type prj_url: C{string} @keyword prj_url: The target for the project hopeage link on the navigation bar. If C{prj_url} is not specified, then no hyperlink is created. @type prj_link: C{string} @keyword prj_link: The label for the project link on the navigation bar. This link can contain arbitrary HTML code (e.g. images). By default, a label is constructed from C{prj_name}. @type top_page: C{string} @keyword top_page: The top page for the documentation. This is the default page shown main frame, when frames are enabled. C{top} can be a URL, the name of a module, the name of a class, or one of the special strings C{"trees.html"}, C{"indices.html"}, or C{"help.html"}. By default, the top-level package or module is used, if there is one; otherwise, C{"trees"} is used. @type css: C{string} @keyword css: The CSS stylesheet file. If C{css} is a file name, then the specified file's conents will be used. Otherwise, if C{css} is the name of a CSS stylesheet in L{epydoc.docwriter.html_css}, then that stylesheet will be used. Otherwise, an error is reported. If no stylesheet is specified, then the default stylesheet is used. @type help_file: C{string} @keyword help_file: The name of the help file. If no help file is specified, then the default help file will be used. @type show_private: C{boolean} @keyword show_private: Whether to create documentation for private objects. By default, private objects are documented. @type show_frames: C{boolean}) @keyword show_frames: Whether to create a frames-based table of contents. By default, it is produced. @type show_imports: C{boolean} @keyword show_imports: Whether or not to display lists of imported functions and classes. By default, they are not shown. @type variable_maxlines: C{int} @keyword variable_maxlines: The maximum number of lines that should be displayed for the value of a variable in the variable details section. By default, 8 lines are displayed. @type variable_linelength: C{int} @keyword variable_linelength: The maximum line length used for displaying the values of variables in the variable details sections. If a line is longer than this length, then it will be wrapped to the next line. The default line length is 70 characters. @type variable_summary_linelength: C{int} @keyword variable_summary_linelength: The maximum line length used for displaying the values of variables in the summary section. If a line is longer than this length, then it will be truncated. The default is 40 characters. @type variable_tooltip_linelength: C{int} @keyword variable_tooltip_linelength: The maximum line length used for tooltips for the values of variables. If a line is longer than this length, then it will be truncated. The default is 600 characters. @type property_function_linelength: C{int} @keyword property_function_linelength: The maximum line length used to dispaly property functions (C{fget}, C{fset}, and C{fdel}) that contain something other than a function object. The default length is 40 characters. @type inheritance: C{string} @keyword inheritance: How inherited objects should be displayed. If C{inheritance='grouped'}, then inherited objects are gathered into groups; if C{inheritance='listed'}, then inherited objects are listed in a short list at the end of their group; if C{inheritance='included'}, then inherited objects are mixed in with non-inherited objects. The default is 'grouped'. @type include_source_code: C{boolean} @keyword include_source_code: If true, then generate colorized source code files for each python module. @type include_log: C{boolean} @keyword include_log: If true, the the footer will include an href to the page 'epydoc-log.html'. @type src_code_tab_width: C{int} @keyword src_code_tab_width: Number of spaces to replace each tab with in source code listings. """ self.docindex = docindex # Process keyword arguments. self._show_private = kwargs.get('show_private', 1) """Should private docs be included?""" self._prj_name = kwargs.get('prj_name', None) """The project's name (for the project link in the navbar)""" self._prj_url = kwargs.get('prj_url', None) """URL for the project link in the navbar""" self._prj_link = kwargs.get('prj_link', None) """HTML code for the project link in the navbar""" self._top_page = kwargs.get('top_page', None) """The 'main' page""" self._css = kwargs.get('css') """CSS stylesheet to use""" self._helpfile = kwargs.get('help_file', None) """Filename of file to extract help contents from""" self._frames_index = kwargs.get('show_frames', 1) """Should a frames index be created?""" self._show_imports = kwargs.get('show_imports', False) """Should imports be listed?""" self._propfunc_linelen = kwargs.get('property_function_linelength', 40) """[XXX] Not used!""" self._variable_maxlines = kwargs.get('variable_maxlines', 8) """Max lines for variable values""" self._variable_linelen = kwargs.get('variable_linelength', 70) """Max line length for variable values""" self._variable_summary_linelen = \ kwargs.get('variable_summary_linelength', 65) """Max length for variable value summaries""" self._variable_tooltip_linelen = \ kwargs.get('variable_tooltip_linelength', 600) """Max length for variable tooltips""" self._inheritance = kwargs.get('inheritance', 'listed') """How should inheritance be displayed? 'listed', 'included', or 'grouped'""" self._incl_sourcecode = kwargs.get('include_source_code', True) """Should pages be generated for source code of modules?""" self._mark_docstrings = kwargs.get('mark_docstrings', False) """Wrap ... around docstrings?""" self._graph_types = kwargs.get('graphs', ()) or () """Graphs that we should include in our output.""" self._include_log = kwargs.get('include_log', False) """Are we generating an HTML log page?""" self._src_code_tab_width = kwargs.get('src_code_tab_width', 8) """Number of spaces to replace each tab with in source code listings.""" self._callgraph_cache = {} """Map the callgraph L{uid} to their HTML representation.""" self._redundant_details = kwargs.get('redundant_details', False) """If true, then include objects in the details list even if all info about them is already provided by the summary table.""" # For use with select_variables(): if self._show_private: self._public_filter = None else: self._public_filter = True # Make sure inheritance has a sane value. if self._inheritance not in ('listed', 'included', 'grouped'): raise ValueError, 'Bad value for inheritance' # Create the project homepage link, if it was not specified. if (self._prj_name or self._prj_url) and not self._prj_link: self._prj_link = plaintext_to_html(self._prj_name or 'Project Homepage') # Add a hyperlink to _prj_url, if _prj_link doesn't already # contain any hyperlinks. if (self._prj_link and self._prj_url and not re.search(r']*\shref', self._prj_link)): self._prj_link = (''+self._prj_link+'') # Precompute lists & sets of APIDoc objects that we're # interested in. self.valdocs = valdocs = sorted(docindex.reachable_valdocs( imports=False, packages=False, bases=False, submodules=False, subclasses=False, private=self._show_private)) self.module_list = [d for d in valdocs if isinstance(d, ModuleDoc)] """The list of L{ModuleDoc}s for the documented modules.""" self.module_set = set(self.module_list) """The set of L{ModuleDoc}s for the documented modules.""" self.class_list = [d for d in valdocs if isinstance(d, ClassDoc)] """The list of L{ClassDoc}s for the documented classes.""" self.class_set = set(self.class_list) """The set of L{ClassDoc}s for the documented classes.""" self.routine_list = [d for d in valdocs if isinstance(d, RoutineDoc)] """The list of L{RoutineDoc}s for the documented routines.""" self.indexed_docs = [] """The list of L{APIDoc}s for variables and values that should be included in the index.""" # URL for 'trees' page if self.module_list: self._trees_url = 'module-tree.html' else: self._trees_url = 'class-tree.html' # Construct the value for self.indexed_docs. self.indexed_docs += [d for d in valdocs if not isinstance(d, GenericValueDoc)] for doc in valdocs: if isinstance(doc, NamespaceDoc): # add any vars with generic values; but don't include # inherited vars. self.indexed_docs += [d for d in doc.variables.values() if isinstance(d.value, GenericValueDoc) and d.container == doc] self.indexed_docs.sort() # Figure out the url for the top page. self._top_page_url = self._find_top_page(self._top_page) # Decide whether or not to split the identifier index. self._split_ident_index = (len(self.indexed_docs) >= self.SPLIT_IDENT_INDEX_SIZE) # Figure out how many output files there will be (for progress # reporting). self.modules_with_sourcecode = set() for doc in self.module_list: if isinstance(doc, ModuleDoc) and is_src_filename(doc.filename): self.modules_with_sourcecode.add(doc) self._num_files = (len(self.class_list) + len(self.module_list) + 10 + len(self.METADATA_INDICES)) if self._frames_index: self._num_files += len(self.module_list) + 3 if self._incl_sourcecode: self._num_files += len(self.modules_with_sourcecode) if self._split_ident_index: self._num_files += len(self.LETTERS) def _find_top_page(self, pagename): """ Find the top page for the API documentation. This page is used as the default page shown in the main frame, when frames are used. When frames are not used, this page is copied to C{index.html}. @param pagename: The name of the page, as specified by the keyword argument C{top} to the constructor. @type pagename: C{string} @return: The URL of the top page. @rtype: C{string} """ # If a page name was specified, then we need to figure out # what it points to. if pagename: # If it's a URL, then use it directly. if pagename.lower().startswith('http:'): return pagename # If it's an object, then use that object's page. try: doc = self.docindex.get_valdoc(pagename) return self.url(doc) except: pass # Otherwise, give up. log.warning('Could not find top page %r; using %s ' 'instead' % (pagename, self._trees_url)) return self._trees_url # If no page name was specified, then try to choose one # automatically. else: root = [val_doc for val_doc in self.docindex.root if isinstance(val_doc, (ClassDoc, ModuleDoc))] if len(root) == 0: # No docs?? Try the trees page. return self._trees_url elif len(root) == 1: # One item in the root; use that. return self.url(root[0]) else: # Multiple root items; if they're all in one package, # then use that. Otherwise, use self._trees_url root = sorted(root, key=lambda v:len(v.canonical_name)) top = root[0] for doc in root[1:]: if not top.canonical_name.dominates(doc.canonical_name): return self._trees_url else: return self.url(top) #//////////////////////////////////////////////////////////// #{ 1. Interface Methods #//////////////////////////////////////////////////////////// def write(self, directory=None): """ Write the documentation to the given directory. @type directory: C{string} @param directory: The directory to which output should be written. If no directory is specified, output will be written to the current directory. If the directory does not exist, it will be created. @rtype: C{None} @raise OSError: If C{directory} cannot be created. @raise OSError: If any file cannot be created or written to. """ # For progress reporting: self._files_written = 0. # Set the default values for ValueDoc formatted representations. orig_valdoc_defaults = (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, ValueDoc.REPR_MAXLINES) ValueDoc.SUMMARY_REPR_LINELEN = self._variable_summary_linelen ValueDoc.REPR_LINELEN = self._variable_linelen ValueDoc.REPR_MAXLINES = self._variable_maxlines # Use an image for the crarr symbol. from epydoc.markup.epytext import ParsedEpytextDocstring orig_crarr_html = ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = ( r'' r'\') # Keep track of failed xrefs, and report them at the end. self._failed_xrefs = {} # Create destination directories, if necessary if not directory: directory = os.curdir self._mkdir(directory) self._directory = directory # Write the CSS file. self._files_written += 1 log.progress(self._files_written/self._num_files, 'epydoc.css') self.write_css(directory, self._css) # Write the Javascript file. self._files_written += 1 log.progress(self._files_written/self._num_files, 'epydoc.js') self.write_javascript(directory) # Write images self.write_images(directory) # Build the indices. indices = {'ident': self.build_identifier_index(), 'term': self.build_term_index()} for (name, label, label2) in self.METADATA_INDICES: indices[name] = self.build_metadata_index(name) # Write the identifier index. If requested, split it into # separate pages for each letter. ident_by_letter = self._group_by_letter(indices['ident']) if not self._split_ident_index: self._write(self.write_link_index, directory, 'identifier-index.html', indices, 'Identifier Index', 'identifier-index.html', ident_by_letter) else: # Write a page for each section. for letter in self.LETTERS: filename = 'identifier-index-%s.html' % letter self._write(self.write_link_index, directory, filename, indices, 'Identifier Index', filename, ident_by_letter, [letter], 'identifier-index-%s.html') # Use the first non-empty section as the main index page. for letter in self.LETTERS: if letter in ident_by_letter: filename = 'identifier-index.html' self._write(self.write_link_index, directory, filename, indices, 'Identifier Index', filename, ident_by_letter, [letter], 'identifier-index-%s.html') break # Write the term index. if indices['term']: term_by_letter = self._group_by_letter(indices['term']) self._write(self.write_link_index, directory, 'term-index.html', indices, 'Term Definition Index', 'term-index.html', term_by_letter) else: self._files_written += 1 # (skipped) # Write the metadata indices. for (name, label, label2) in self.METADATA_INDICES: if indices[name]: self._write(self.write_metadata_index, directory, '%s-index.html' % name, indices, name, label, label2) else: self._files_written += 1 # (skipped) # Write the trees file (package & class hierarchies) if self.module_list: self._write(self.write_module_tree, directory, 'module-tree.html') else: self._files_written += 1 # (skipped) if self.class_list: self._write(self.write_class_tree, directory, 'class-tree.html') else: self._files_written += 1 # (skipped) # Write the help file. self._write(self.write_help, directory,'help.html') # Write the frames-based table of contents. if self._frames_index: self._write(self.write_frames_index, directory, 'frames.html') self._write(self.write_toc, directory, 'toc.html') self._write(self.write_project_toc, directory, 'toc-everything.html') for doc in self.module_list: filename = 'toc-%s' % urllib.unquote(self.url(doc)) self._write(self.write_module_toc, directory, filename, doc) # Write the object documentation. for doc in self.module_list: filename = urllib.unquote(self.url(doc)) self._write(self.write_module, directory, filename, doc) for doc in self.class_list: filename = urllib.unquote(self.url(doc)) self._write(self.write_class, directory, filename, doc) # Write source code files. if self._incl_sourcecode: # Build a map from short names to APIDocs, used when # linking names in the source code. name_to_docs = {} for api_doc in self.indexed_docs: if (api_doc.canonical_name is not None and self.url(api_doc) is not None): name = api_doc.canonical_name[-1] name_to_docs.setdefault(name, []).append(api_doc) # Sort each entry of the name_to_docs list. for doc_list in name_to_docs.values(): doc_list.sort() # Write the source code for each module. for doc in self.modules_with_sourcecode: filename = urllib.unquote(self.pysrc_url(doc)) self._write(self.write_sourcecode, directory, filename, doc, name_to_docs) # Write the auto-redirect page. self._write(self.write_redirect_page, directory, 'redirect.html') # Write the mapping object name -> URL self._write(self.write_api_list, directory, 'api-objects.txt') # Write the index.html files. # (this must be done last, since it might copy another file) self._files_written += 1 log.progress(self._files_written/self._num_files, 'index.html') self.write_homepage(directory) # Don't report references to builtins as missing for k in self._failed_xrefs.keys(): # have a copy of keys if hasattr(__builtin__, k): del self._failed_xrefs[k] # Report any failed crossreferences if self._failed_xrefs: estr = 'Failed identifier crossreference targets:\n' failed_identifiers = self._failed_xrefs.keys() failed_identifiers.sort() for identifier in failed_identifiers: names = self._failed_xrefs[identifier].keys() names.sort() estr += '- %s' % identifier estr += '\n' for name in names: estr += ' (from %s)\n' % name log.docstring_warning(estr) # [xx] testing: if self._num_files != int(self._files_written): log.debug("Expected to write %d files, but actually " "wrote %d files" % (self._num_files, int(self._files_written))) # Restore defaults that we changed. (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, ValueDoc.REPR_MAXLINES) = orig_valdoc_defaults ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = orig_crarr_html def _write(self, write_func, directory, filename, *args): # Display our progress. self._files_written += 1 log.progress(self._files_written/self._num_files, filename) path = os.path.join(directory, filename) f = codecs.open(path, 'w', 'ascii', errors='xmlcharrefreplace') write_func(f.write, *args) f.close() def _mkdir(self, directory): """ If the given directory does not exist, then attempt to create it. @rtype: C{None} """ if not os.path.isdir(directory): if os.path.exists(directory): raise OSError('%r is not a directory' % directory) os.mkdir(directory) #//////////////////////////////////////////////////////////// #{ 2.1. Module Pages #//////////////////////////////////////////////////////////// def write_module(self, out, doc): """ Write an HTML page containing the API documentation for the given module to C{out}. @param doc: A L{ModuleDoc} containing the API documentation for the module that should be described. """ longname = doc.canonical_name shortname = doc.canonical_name[-1] # Write the page header (incl. navigation bar & breadcrumbs) self.write_header(out, str(longname)) self.write_navbar(out, doc) self.write_breadcrumbs(out, doc, self.url(doc)) # Write the name of the module we're describing. if doc.is_package is True: typ = 'Package' else: typ = 'Module' if longname[0].startswith('script-'): shortname = str(longname)[7:] typ = 'Script' out('\n') out('

%s %s

' % (typ, shortname)) out('

%s

\n' % self.pysrc_link(doc)) # If the module has a description, then list it. if doc.descr not in (None, UNKNOWN): out(self.descr(doc, 2)+'\n\n') # Write any standarad metadata (todo, author, etc.) if doc.metadata is not UNKNOWN and doc.metadata: out('
\n') self.write_standard_fields(out, doc) # If it's a package, then list the modules it contains. if doc.is_package is True: self.write_module_list(out, doc) # Write summary tables describing the variables that the # module defines. self.write_summary_table(out, "Classes", doc, "class") self.write_summary_table(out, "Functions", doc, "function") self.write_summary_table(out, "Variables", doc, "other") # Write a list of all imported objects. if self._show_imports: self.write_imports(out, doc) # Write detailed descriptions of functions & variables defined # in this module. self.write_details_list(out, "Function Details", doc, "function") self.write_details_list(out, "Variables Details", doc, "other") # Write the page footer (including navigation bar) self.write_navbar(out, doc) self.write_footer(out) #//////////////////////////////////////////////////////////// #{ 2.??. Source Code Pages #//////////////////////////////////////////////////////////// def write_sourcecode(self, out, doc, name_to_docs): #t0 = time.time() filename = doc.filename name = str(doc.canonical_name) # Header self.write_header(out, name) self.write_navbar(out, doc) self.write_breadcrumbs(out, doc, self.pysrc_url(doc)) # Source code listing out('

Source Code for %s

\n' % self.href(doc, label='%s %s' % (self.doc_kind(doc), name))) out('
\n')
        out(PythonSourceColorizer(filename, name, self.docindex,
                                  self.url, name_to_docs,
                                  self._src_code_tab_width).colorize())
        out('
\n
\n') # Footer self.write_navbar(out, doc) self.write_footer(out) #log.debug('[%6.2f sec] Wrote pysrc for %s' % # (time.time()-t0, name)) #//////////////////////////////////////////////////////////// #{ 2.2. Class Pages #//////////////////////////////////////////////////////////// def write_class(self, out, doc): """ Write an HTML page containing the API documentation for the given class to C{out}. @param doc: A L{ClassDoc} containing the API documentation for the class that should be described. """ longname = doc.canonical_name shortname = doc.canonical_name[-1] # Write the page header (incl. navigation bar & breadcrumbs) self.write_header(out, str(longname)) self.write_navbar(out, doc) self.write_breadcrumbs(out, doc, self.url(doc)) # Write the name of the class we're describing. if doc.is_type(): typ = 'Type' elif doc.is_exception(): typ = 'Exception' else: typ = 'Class' out('\n') out('

%s %s

' % (typ, shortname)) out('

%s

\n' % self.pysrc_link(doc)) if ((doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0) or (doc.subclasses not in (UNKNOWN,None) and len(doc.subclasses)>0)): # Display bases graphically, if requested. if 'umlclasstree' in self._graph_types: self.write_class_tree_graph(out, doc, uml_class_tree_graph) elif 'classtree' in self._graph_types: self.write_class_tree_graph(out, doc, class_tree_graph) # Otherwise, use ascii-art. else: # Write the base class tree. if doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0: out('
\n%s
\n\n' % self.base_tree(doc)) # Write the known subclasses if (doc.subclasses not in (UNKNOWN, None) and len(doc.subclasses) > 0): out('
Known Subclasses:
\n
\n ') out('
    \n') for i, subclass in enumerate(doc.subclasses): href = self.href(subclass, context=doc) if self._val_is_public(subclass): css = '' else: css = ' class="private"' if i > 0: href = ', '+href out('%s' % (css, href)) out('
\n') out('
\n\n') out('
\n') # If the class has a description, then list it. if doc.descr not in (None, UNKNOWN): out(self.descr(doc, 2)+'\n\n') # Write any standarad metadata (todo, author, etc.) if doc.metadata is not UNKNOWN and doc.metadata: out('
\n') self.write_standard_fields(out, doc) # Write summary tables describing the variables that the # class defines. self.write_summary_table(out, "Nested Classes", doc, "class") self.write_summary_table(out, "Instance Methods", doc, "instancemethod") self.write_summary_table(out, "Class Methods", doc, "classmethod") self.write_summary_table(out, "Static Methods", doc, "staticmethod") self.write_summary_table(out, "Class Variables", doc, "classvariable") self.write_summary_table(out, "Instance Variables", doc, "instancevariable") self.write_summary_table(out, "Properties", doc, "property") # Write a list of all imported objects. if self._show_imports: self.write_imports(out, doc) # Write detailed descriptions of functions & variables defined # in this class. # [xx] why group methods into one section but split vars into two? # seems like we should either group in both cases or split in both # cases. self.write_details_list(out, "Method Details", doc, "method") self.write_details_list(out, "Class Variable Details", doc, "classvariable") self.write_details_list(out, "Instance Variable Details", doc, "instancevariable") self.write_details_list(out, "Property Details", doc, "property") # Write the page footer (including navigation bar) self.write_navbar(out, doc) self.write_footer(out) def write_class_tree_graph(self, out, doc, graphmaker): """ Write HTML code for a class tree graph of C{doc} (a classdoc), using C{graphmaker} to draw the actual graph. C{graphmaker} should be L{class_tree_graph()}, or L{uml_class_tree_graph()}, or any other function with a compatible signature. If the given class has any private sublcasses (including recursive subclasses), then two graph images will be generated -- one to display when private values are shown, and the other to display when private values are hidden. """ linker = _HTMLDocstringLinker(self, doc) private_subcls = self._private_subclasses(doc) if private_subcls: out('
\n' '
%s
\n' ' \n' '
\n' % (self.render_graph(graphmaker(doc, linker, doc)), self.render_graph(graphmaker(doc, linker, doc, exclude=private_subcls)))) else: out('
\n%s\n
\n' % self.render_graph(graphmaker(doc, linker, doc))) #//////////////////////////////////////////////////////////// #{ 2.3. Trees pages #//////////////////////////////////////////////////////////// def write_module_tree(self, out): # Header material self.write_treepage_header(out, 'Module Hierarchy', 'module-tree.html') out('

Module Hierarchy

\n') # Write entries for all top-level modules/packages. out('
    \n') for doc in self.module_list: if (doc.package in (None, UNKNOWN) or doc.package not in self.module_set): self.write_module_tree_item(out, doc) out('
\n') # Footer material self.write_navbar(out, 'trees') self.write_footer(out) def write_class_tree(self, out): """ Write HTML code for a nested list showing the base/subclass relationships between all documented classes. Each element of the top-level list is a class with no (documented) bases; and under each class is listed all of its subclasses. Note that in the case of multiple inheritance, a class may appear multiple times. @todo: For multiple inheritance, don't repeat subclasses the second time a class is mentioned; instead, link to the first mention. """ # [XX] backref for multiple inheritance? # Header material self.write_treepage_header(out, 'Class Hierarchy', 'class-tree.html') out('

Class Hierarchy

\n') # Build a set containing all classes that we should list. # This includes everything in class_list, plus any of those # class' bases, but not undocumented subclasses. class_set = self.class_set.copy() for doc in self.class_list: if doc.bases != UNKNOWN: for base in doc.bases: if base not in class_set: if isinstance(base, ClassDoc): class_set.update(base.mro()) else: # [XX] need to deal with this -- how? pass #class_set.add(base) out('
    \n') for doc in sorted(class_set, key=lambda c:c.canonical_name[-1]): if doc.bases != UNKNOWN and len(doc.bases)==0: self.write_class_tree_item(out, doc, class_set) out('
\n') # Footer material self.write_navbar(out, 'trees') self.write_footer(out) def write_treepage_header(self, out, title, url): # Header material. self.write_header(out, title) self.write_navbar(out, 'trees') self.write_breadcrumbs(out, 'trees', url) if self.class_list and self.module_list: out('
\n') out(' [ Module Hierarchy\n') out(' | Class Hierarchy ]\n') out('

\n') #//////////////////////////////////////////////////////////// #{ 2.4. Index pages #//////////////////////////////////////////////////////////// SPLIT_IDENT_INDEX_SIZE = 3000 """If the identifier index has more than this number of entries, then it will be split into separate pages, one for each alphabetical section.""" LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' """The alphabetical sections that are used for link index pages.""" def write_link_index(self, out, indices, title, url, index_by_section, sections=LETTERS, section_url='#%s'): # Header self.write_indexpage_header(out, indices, title, url) # Index title & links to alphabetical sections. out('\n' '
\n') out('

%s

\n
\n[\n' % title) for sec in self.LETTERS: if sec in index_by_section: out(' %s\n' % (section_url % sec, sec)) else: out(' %s\n' % sec) out(']\n') out('
\n') # Alphabetical sections. sections = [s for s in sections if s in index_by_section] if sections: out('\n') for section in sorted(sections): out('\n' % (section, section)) out('\n') out('
') out('

%s

\n') self.write_index_section(out, index_by_section[section], True) out('
\n
') # Footer material. out('
') self.write_navbar(out, 'indices') self.write_footer(out) def write_metadata_index(self, out, indices, field, title, typ): """ Write an HTML page containing a metadata index. """ index = indices[field] # Header material. self.write_indexpage_header(out, indices, title, '%s-index.html' % field) # Page title. out('

%s

\n
\n' % (field, title)) # Index (one section per arg) for arg in sorted(index): # Write a section title. if arg is not None: if len([1 for (doc, descrs) in index[arg] if not self._doc_or_ancestor_is_private(doc)]) == 0: out('
') else: out('
') self.write_table_header(out, 'metadata-index', arg) out('') # List every descr for this arg. for (doc, descrs) in index[arg]: if self._doc_or_ancestor_is_private(doc): out('
\n') else: out('
\n') out('
\n') # Footer material. out('
') self.write_navbar(out, 'indices') self.write_footer(out) def write_indexpage_header(self, out, indices, title, url): """ A helper for the index page generation functions, which generates a header that can be used to navigate between the different indices. """ self.write_header(out, title) self.write_navbar(out, 'indices') self.write_breadcrumbs(out, 'indices', url) if (indices['term'] or [1 for (name,l,l2) in self.METADATA_INDICES if indices[name]]): out('
[\n') out(' Identifiers\n') if indices['term']: out('| Term Definitions\n') for (name, label, label2) in self.METADATA_INDICES: if indices[name]: out('| %s\n' % (name, label2)) out(']

\n') def write_index_section(self, out, items, add_blankline=False): out('\n') num_rows = (len(items)+2)/3 for row in range(num_rows): out('\n') for col in range(3): out('\n') out('\n') if add_blankline and num_rows == 1: blank_cell = '' out(''+3*blank_cell+'\n') out('\n') #//////////////////////////////////////////////////////////// #{ 2.5. Help Page #//////////////////////////////////////////////////////////// def write_help(self, out): """ Write an HTML help file to the given stream. If C{self._helpfile} contains a help file, then use it; otherwise, use the default helpfile from L{epydoc.docwriter.html_help}. """ # todo: optionally parse .rst etc help files? # Get the contents of the help file. if self._helpfile: if os.path.exists(self._helpfile): try: help = open(self._helpfile).read() except: raise IOError("Can't open help file: %r" % self._helpfile) else: raise IOError("Can't find help file: %r" % self._helpfile) else: if self._prj_name: thisprj = self._prj_name else: thisprj = 'this project' help = HTML_HELP % {'this_project':thisprj} # Insert the help contents into a webpage. self.write_header(out, 'Help') self.write_navbar(out, 'help') self.write_breadcrumbs(out, 'help', 'help.html') out(help) self.write_navbar(out, 'help') self.write_footer(out) #//////////////////////////////////////////////////////////// #{ 2.6. Frames-based Table of Contents #//////////////////////////////////////////////////////////// write_frames_index = compile_template( """ write_frames_index(self, out) Write the frames index file for the frames-based table of contents to the given streams. """, # /------------------------- Template -------------------------\ ''' $self._prj_name or "API Documentation"$ ''') # \------------------------------------------------------------/ write_toc = compile_template( """ write_toc(self, out) """, # /------------------------- Template -------------------------\ ''' >>> self.write_header(out, "Table of Contents")

Table of Contents


Everything
>>> self.write_toc_section(out, "Modules", self.module_list)
>>> if self._show_private: $self.PRIVATE_LINK$ >>> #endif >>> self.write_footer(out, short=True) ''') # \------------------------------------------------------------/ def write_toc_section(self, out, name, docs, fullname=True): if not docs: return # Assign names to each item, and sort by name. if fullname: docs = [(str(d.canonical_name), d) for d in docs] else: docs = [(str(d.canonical_name[-1]), d) for d in docs] docs.sort() out('

%s

\n' % name) for label, doc in docs: doc_url = self.url(doc) toc_url = 'toc-%s' % doc_url is_private = self._doc_or_ancestor_is_private(doc) if is_private: if not self._show_private: continue out('
\n') if isinstance(doc, ModuleDoc): out(' %s
' % (toc_url, toc_url, doc_url, label)) else: out(' %s
' % (doc_url, label)) if is_private: out('
\n') def write_project_toc(self, out): self.write_header(out, "Everything") out('

Everything

\n') out('
\n') # List the classes. self.write_toc_section(out, "All Classes", self.class_list) # List the functions. funcs = [d for d in self.routine_list if not isinstance(self.docindex.container(d), (ClassDoc, types.NoneType))] self.write_toc_section(out, "All Functions", funcs) # List the variables. vars = [] for doc in self.module_list: vars += doc.select_variables(value_type='other', imported=False, public=self._public_filter) self.write_toc_section(out, "All Variables", vars) # Footer material. out('
\n') if self._show_private: out(self.PRIVATE_LINK+'\n') self.write_footer(out, short=True) def write_module_toc(self, out, doc): """ Write an HTML page containing the table of contents page for the given module to the given streams. This page lists the modules, classes, exceptions, functions, and variables defined by the module. """ name = doc.canonical_name[-1] self.write_header(out, name) out('

Module %s

\n' % name) out('
\n') # List the classes. classes = doc.select_variables(value_type='class', imported=False, public=self._public_filter) self.write_toc_section(out, "Classes", classes, fullname=False) # List the functions. funcs = doc.select_variables(value_type='function', imported=False, public=self._public_filter) self.write_toc_section(out, "Functions", funcs, fullname=False) # List the variables. variables = doc.select_variables(value_type='other', imported=False, public=self._public_filter) self.write_toc_section(out, "Variables", variables, fullname=False) # Footer material. out('
\n') if self._show_private: out(self.PRIVATE_LINK+'\n') self.write_footer(out, short=True) #//////////////////////////////////////////////////////////// #{ 2.7. Project homepage (index.html) #//////////////////////////////////////////////////////////// def write_homepage(self, directory): """ Write an C{index.html} file in the given directory. The contents of this file are copied or linked from an existing page, so this method must be called after all pages have been written. The page used is determined by L{_frames_index} and L{_top_page}: - If L{_frames_index} is true, then C{frames.html} is copied. - Otherwise, the page specified by L{_top_page} is copied. """ filename = os.path.join(directory, 'index.html') if self._frames_index: top = 'frames.html' else: top = self._top_page_url # Copy the non-frames index file from top, if it's internal. if top[:5] != 'http:' and '/' not in top: try: # Read top into `s`. topfile = os.path.join(directory, top) s = open(topfile, 'r').read() # Write the output file. open(filename, 'w').write(s) return except: log.error('Warning: error copying index; ' 'using a redirect page') # Use a redirect if top is external, or if we faild to copy. name = self._prj_name or 'this project' f = open(filename, 'w') self.write_redirect_index(f.write, top, name) f.close() write_redirect_index = compile_template( """ write_redirect_index(self, out, top, name) """, # /------------------------- Template -------------------------\ ''' Redirect

Redirecting to the API documentation for $self._prj_name or "this project"$...

''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ 2.8. Stylesheet (epydoc.css) #//////////////////////////////////////////////////////////// def write_css(self, directory, cssname): """ Write the CSS stylesheet in the given directory. If C{cssname} contains a stylesheet file or name (from L{epydoc.docwriter.html_css}), then use that stylesheet; otherwise, use the default stylesheet. @rtype: C{None} """ filename = os.path.join(directory, 'epydoc.css') # Get the contents for the stylesheet file. if cssname is None: css = STYLESHEETS['default'][0] else: if os.path.exists(cssname): try: css = open(cssname).read() except: raise IOError("Can't open CSS file: %r" % cssname) elif cssname in STYLESHEETS: css = STYLESHEETS[cssname][0] else: raise IOError("Can't find CSS file: %r" % cssname) # Write the stylesheet. cssfile = open(filename, 'w') cssfile.write(css) cssfile.close() #//////////////////////////////////////////////////////////// #{ 2.9. Javascript (epydoc.js) #//////////////////////////////////////////////////////////// def write_javascript(self, directory): jsfile = open(os.path.join(directory, 'epydoc.js'), 'w') print >> jsfile, self.TOGGLE_PRIVATE_JS print >> jsfile, self.SHOW_PRIVATE_JS print >> jsfile, self.GET_COOKIE_JS print >> jsfile, self.SET_FRAME_JS print >> jsfile, self.HIDE_PRIVATE_JS print >> jsfile, self.TOGGLE_CALLGRAPH_JS print >> jsfile, html_colorize.PYSRC_JAVASCRIPTS print >> jsfile, self.GET_ANCHOR_JS print >> jsfile, self.REDIRECT_URL_JS jsfile.close() #: A javascript that is used to show or hide the API documentation #: for private objects. In order for this to work correctly, all #: documentation for private objects should be enclosed in #: C{
...
} elements. TOGGLE_PRIVATE_JS = ''' function toggle_private() { // Search for any private/public links on this page. Store // their old text in "cmd," so we will know what action to // take; and change their text to the opposite action. var cmd = "?"; var elts = document.getElementsByTagName("a"); for(var i=0; i, they will #: automatically get redirected to the page for the object with #: the given fully-qualified dotted name. E.g., for epydoc, #: redirects the user to #: . REDIRECT_URL_JS = ''' function redirect_url(dottedName) { // Scan through each element of the "pages" list, and check // if "name" matches with any of them. for (var i=0; i-m" or "-c"; // extract the portion & compare it to dottedName. var pagename = pages[i].substring(0, pages[i].length-2); if (pagename == dottedName.substring(0,pagename.length)) { // We\'ve found a page that matches `dottedName`; // construct its URL, using leftover `dottedName` // content to form an anchor. var pagetype = pages[i].charAt(pages[i].length-1); var url = pagename + ((pagetype=="m")?"-module.html": "-class.html"); if (dottedName.length > pagename.length) url += "#" + dottedName.substring(pagename.length+1, dottedName.length); return url; } } } '''.strip() #//////////////////////////////////////////////////////////// #{ 2.10. Graphs #//////////////////////////////////////////////////////////// def render_graph(self, graph): if graph is None: return '' graph.caption = graph.title = None image_url = '%s.gif' % graph.uid image_file = os.path.join(self._directory, image_url) return graph.to_html(image_file, image_url) RE_CALLGRAPH_ID = re.compile(r"""["'](.+-div)['"]""") def render_callgraph(self, callgraph, token=""): """Render the HTML chunk of a callgraph. If C{callgraph} is a string, use the L{_callgraph_cache} to return a pre-rendered HTML chunk. This mostly avoids to run C{dot} twice for the same callgraph. Else, run the graph and store its HTML output in the cache. @param callgraph: The graph to render or its L{uid}. @type callgraph: L{DotGraph} or C{str} @param token: A string that can be used to make the C{
} id unambiguous, if the callgraph is used more than once in a page. @type token: C{str} @return: The HTML representation of the graph. @rtype: C{str} """ if callgraph is None: return "" if isinstance(callgraph, basestring): uid = callgraph rv = self._callgraph_cache.get(callgraph, "") else: uid = callgraph.uid graph_html = self.render_graph(callgraph) if graph_html == '': rv = "" else: rv = ('\n' % graph_html) # Store in the cache the complete HTML chunk without the # div id, which may be made unambiguous by the token self._callgraph_cache[uid] = rv # Mangle with the graph if rv: rv = rv % (uid + token) return rv def callgraph_link(self, callgraph, token=""): """Render the HTML chunk of a callgraph link. The link can toggles the visibility of the callgraph rendered using L{render_callgraph} with matching parameters. @param callgraph: The graph to render or its L{uid}. @type callgraph: L{DotGraph} or C{str} @param token: A string that can be used to make the C{
} id unambiguous, if the callgraph is used more than once in a page. @type token: C{str} @return: The HTML representation of the graph link. @rtype: C{str} """ # Use class=codelink, to match style w/ the source code link. if callgraph is None: return '' if isinstance(callgraph, basestring): uid = callgraph else: uid = callgraph.uid return ('
' 'call graph ' % (uid + token)) #//////////////////////////////////////////////////////////// #{ 2.11. Images #//////////////////////////////////////////////////////////// IMAGES = {'crarr.png': # Carriage-return arrow, used for LINEWRAP. 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAMAAABlokWQAAAALHRFWHRD' 'cmVhdGlvbiBUaW1lAFR1\nZSAyMiBBdWcgMjAwNiAwMDo0MzoxMCAtMD' 'UwMGAMEFgAAAAHdElNRQfWCBYFASkQ033WAAAACXBI\nWXMAAB7CAAAe' 'wgFu0HU+AAAABGdBTUEAALGPC/xhBQAAAEVQTFRF////zcOw18/AgGY0' 'c1cg4dvQ\ninJEYEAAYkME3NXI6eTcloFYe2Asr5+AbE4Uh29A9fPwqp' 'l4ZEUI8O3onopk0Ma0lH5U1nfFdgAA\nAAF0Uk5TAEDm2GYAAABNSURB' 'VHjaY2BAAbzsvDAmK5oIlxgfioiwCAe7KJKIgKAQOzsLLwTwA0VY\n+d' 'iRAT8T0AxuIIMHqoaXCWIPGzsHJ6orGJiYWRjQASOcBQAocgMSPKMTIg' 'AAAABJRU5ErkJggg==\n', } def write_images(self, directory): for (name, data) in self.IMAGES.items(): f = open(os.path.join(directory, name), 'wb') f.write(base64.decodestring(data)) f.close() #//////////////////////////////////////////////////////////// #{ 3.1. Page Header #//////////////////////////////////////////////////////////// write_header = compile_template( """ write_header(self, out, title) Generate HTML code for the standard page header, and write it to C{out}. C{title} is a string containing the page title. It should be appropriately escaped/encoded. """, # /------------------------- Template -------------------------\ ''' $title$ ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ 3.2. Page Footer #//////////////////////////////////////////////////////////// write_footer = compile_template( """ write_footer(self, out, short=False) Generate HTML code for the standard page footer, and write it to C{out}. """, # /------------------------- Template -------------------------\ ''' >>> if not short:
>>> #endif ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ 3.3. Navigation Bar #//////////////////////////////////////////////////////////// write_navbar = compile_template( """ write_navbar(self, out, context) Generate HTML code for the navigation bar, and write it to C{out}. The navigation bar typically looks like:: [ Home Trees Index Help Project ] @param context: A value indicating what page we're generating a navigation bar for. If we're generating an API documentation page for an object, then C{context} is a L{ValueDoc} containing the documentation for that object; otherwise, C{context} is a string name for the page. The following string names are recognized: C{'tree'}, C{'index'}, and C{'help'}. """, # /------------------------- Template -------------------------\ ''' >>> if self._top_page_url not in (self._trees_url, "identifier-index.html", "help.html"): >>> if (isinstance(context, ValueDoc) and >>> self._top_page_url == self.url(context.canonical_name)): >>> else: >>> #endif >>> if context == "trees": >>> else: >>> #endif >>> if context == "indices": >>> else: >>> #endif >>> if context == "help": >>> else: >>> #endif >>> if self._prj_link: >>> else: >>> #endif ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ 3.4. Breadcrumbs #//////////////////////////////////////////////////////////// write_breadcrumbs = compile_template( """ write_breadcrumbs(self, out, context, context_url) Generate HTML for the breadcrumbs line, and write it to C{out}. The breadcrumbs line is an invisible table with a list of pointers to the current object's ancestors on the left; and the show/hide private selector and the frames/noframes selector on the right. @param context: The API documentation for the object whose breadcrumbs we should generate. @type context: L{ValueDoc} """, # /------------------------- Template -------------------------\ ''' >>> if isinstance(context, APIDoc): >>> else: >>> #endif
>>> crumbs = self.breadcrumbs(context) >>> for crumb in crumbs[:-1]: $crumb$ :: >>> #endfor $crumbs[-1]$   >>> if self._show_private: >>> #endif >>> if self._frames_index: >>> #endif
$self.PRIVATE_LINK$
[frames] | no frames]
''') # \------------------------------------------------------------/ def breadcrumbs(self, doc): crumbs = [self._crumb(doc)] # Generate the crumbs for uid's ancestors. while True: container = self.docindex.container(doc) assert doc != container, 'object is its own container?' if container is None: if doc.canonical_name is UNKNOWN: return ['??']+crumbs elif isinstance(doc, ModuleDoc): return ['Package %s' % ident for ident in doc.canonical_name[:-1]]+crumbs else: return list(doc.canonical_name)+crumbs else: label = self._crumb(container) name = container.canonical_name crumbs.insert(0, self.href(container, label)) # [xx] code=0?? doc = container def _crumb(self, doc): if (len(doc.canonical_name)==1 and doc.canonical_name[0].startswith('script-')): return 'Script %s' % doc.canonical_name[0][7:] return '%s %s' % (self.doc_kind(doc), doc.canonical_name[-1]) #//////////////////////////////////////////////////////////// #{ 3.5. Summary Tables #//////////////////////////////////////////////////////////// def write_summary_table(self, out, heading, doc, value_type): """ Generate HTML code for a summary table, and write it to C{out}. A summary table is a table that includes a one-row description for each variable (of a given type) in a module or class. @param heading: The heading for the summary table; typically, this indicates what kind of value the table describes (e.g., functions or classes). @param doc: A L{ValueDoc} object containing the API documentation for the module or class whose variables we should summarize. @param value_type: A string indicating what type of value should be listed in this summary table. This value is passed on to C{doc}'s C{select_variables()} method. """ # inh_var_groups is a dictionary used to hold "inheritance # pseudo-groups", which are created when inheritance is # 'grouped'. It maps each base to a list of vars inherited # from that base. grouped_inh_vars = {} # Divide all public variables of the given type into groups. groups = [(plaintext_to_html(group_name), doc.select_variables(group=group_name, imported=False, value_type=value_type, public=self._public_filter)) for group_name in doc.group_names()] # Discard any empty groups; and return if they're all empty. groups = [(g,vars) for (g,vars) in groups if vars] if not groups: return # Write a header self.write_table_header(out, "summary", heading) # Write a section for each group. for name, var_docs in groups: self.write_summary_group(out, doc, name, var_docs, grouped_inh_vars) # Write a section for each inheritance pseudo-group (used if # inheritance=='grouped') if grouped_inh_vars: for base in doc.mro(): if base in grouped_inh_vars: hdr = 'Inherited from %s' % self.href(base, context=doc) tr_class = '' if len([v for v in grouped_inh_vars[base] if v.is_public]) == 0: tr_class = ' class="private"' self.write_group_header(out, hdr, tr_class) for var_doc in grouped_inh_vars[base]: self.write_summary_line(out, var_doc, doc) # Write a footer for the table. out(self.TABLE_FOOTER) def write_summary_group(self, out, doc, name, var_docs, grouped_inh_vars): # Split up the var_docs list, according to the way each var # should be displayed: # - listed_inh_vars -- for listed inherited variables. # - grouped_inh_vars -- for grouped inherited variables. # - normal_vars -- for all other variables. listed_inh_vars = {} normal_vars = [] for var_doc in var_docs: if var_doc.container != doc: base = var_doc.container if not isinstance(base, ClassDoc): # This *should* never happen: log.warning("%s's container is not a class!" % var_doc) normal_vars.append(var_doc) elif (base not in self.class_set or self._inheritance == 'listed'): listed_inh_vars.setdefault(base,[]).append(var_doc) elif self._inheritance == 'grouped': grouped_inh_vars.setdefault(base,[]).append(var_doc) else: normal_vars.append(var_doc) else: normal_vars.append(var_doc) # Write a header for the group. if name != '': tr_class = '' if len([v for v in var_docs if v.is_public]) == 0: tr_class = ' class="private"' self.write_group_header(out, name, tr_class) # Write a line for each normal var: for var_doc in normal_vars: self.write_summary_line(out, var_doc, doc) # Write a subsection for inherited vars: if listed_inh_vars: self.write_inheritance_list(out, doc, listed_inh_vars) def write_inheritance_list(self, out, doc, listed_inh_vars): out(' \n \n') for base in doc.mro(): if base not in listed_inh_vars: continue public_vars = [v for v in listed_inh_vars[base] if v.is_public] private_vars = [v for v in listed_inh_vars[base] if not v.is_public] if public_vars: out('

' 'Inherited from %s:\n' % self.href(base, context=doc)) self.write_var_list(out, public_vars) out('

\n') if private_vars and self._show_private: out('
') out('

' 'Inherited from %s (private):\n' % self.href(base, context=doc)) self.write_var_list(out, private_vars) out('

\n') out(' \n \n') def write_var_list(self, out, vardocs): out(' ') out(',\n '.join(['%s' % self.href(v,v.name) for v in vardocs])+'\n') def write_summary_line(self, out, var_doc, container): """ Generate HTML code for a single line of a summary table, and write it to C{out}. See L{write_summary_table} for more information. @param var_doc: The API documentation for the variable that should be described by this line of the summary table. @param container: The API documentation for the class or module whose summary table we're writing. """ pysrc_link = None callgraph = None # If it's a private variable, then mark its . if var_doc.is_public: tr_class = '' else: tr_class = ' class="private"' # Decide an anchor or a link is to be generated. link_name = self._redundant_details or var_doc.is_detailed() anchor = not link_name # Construct the HTML code for the type (cell 1) & description # (cell 2). if isinstance(var_doc.value, RoutineDoc): typ = self.return_type(var_doc, indent=6) description = self.function_signature(var_doc, is_summary=True, link_name=link_name, anchor=anchor) pysrc_link = self.pysrc_link(var_doc.value) # Perpare the call-graph, if requested if 'callgraph' in self._graph_types: linker = _HTMLDocstringLinker(self, var_doc.value) callgraph = call_graph([var_doc.value], self.docindex, linker, var_doc, add_callers=True, add_callees=True) if callgraph and callgraph.nodes: var_doc.value.callgraph_uid = callgraph.uid else: callgraph = None else: typ = self.type_descr(var_doc, indent=6) description = self.summary_name(var_doc, link_name=link_name, anchor=anchor) if isinstance(var_doc.value, GenericValueDoc): # The summary max length has been chosen setting # L{ValueDoc.SUMMARY_REPR_LINELEN} in the constructor max_len=self._variable_summary_linelen-3-len(var_doc.name) val_repr = var_doc.value.summary_pyval_repr(max_len) tooltip = self.variable_tooltip(var_doc) description += (' = %s' % (tooltip, val_repr.to_html(None))) # Add the summary to the description (if there is one). summary = self.summary(var_doc, indent=6) if summary: description += '
\n %s' % summary # If it's inherited, then add a note to the description. if var_doc.container != container and self._inheritance=="included": description += ("\n (Inherited from " + self.href(var_doc.container) + ")") # Write the summary line. self._write_summary_line(out, typ, description, tr_class, pysrc_link, callgraph) _write_summary_line = compile_template( "_write_summary_line(self, out, typ, description, tr_class, " "pysrc_link, callgraph)", # /------------------------- Template -------------------------\ ''' $typ or " "$ >>> if pysrc_link is not None or callgraph is not None:
$description$ $pysrc_link$ $self.callgraph_link(callgraph, token='-summary')$
$self.render_callgraph(callgraph, token='-summary')$ >>> #endif >>> if pysrc_link is None and callgraph is None: $description$ >>> #endif ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ 3.6. Details Lists #//////////////////////////////////////////////////////////// def write_details_list(self, out, heading, doc, value_type): # Get a list of the VarDocs we should describe. if self._redundant_details: detailed = None else: detailed = True if isinstance(doc, ClassDoc): var_docs = doc.select_variables(value_type=value_type, imported=False, inherited=False, public=self._public_filter, detailed=detailed) else: var_docs = doc.select_variables(value_type=value_type, imported=False, public=self._public_filter, detailed=detailed) if not var_docs: return # Write a header self.write_table_header(out, "details", heading) out(self.TABLE_FOOTER) for var_doc in var_docs: self.write_details_entry(out, var_doc) out('
\n') def write_details_entry(self, out, var_doc): descr = self.descr(var_doc, indent=2) or '' if var_doc.is_public: div_class = '' else: div_class = ' class="private"' # Functions if isinstance(var_doc.value, RoutineDoc): rtype = self.return_type(var_doc, indent=10) rdescr = self.return_descr(var_doc, indent=10) arg_descrs = [] args = set() # Find the description for each arg. (Leave them in the # same order that they're listed in the docstring.) for (arg_names, arg_descr) in var_doc.value.arg_descrs: args.update(arg_names) lhs = ', '.join([self.arg_name_to_html(var_doc.value, n) for n in arg_names]) rhs = self.docstring_to_html(arg_descr, var_doc.value, 10) arg_descrs.append( (lhs, rhs) ) # Check for arguments for which we have @type but not @param; # and add them to the arg_descrs list. for arg in var_doc.value.arg_types: if arg not in args: argname = self.arg_name_to_html(var_doc.value, arg) arg_descrs.append( (argname,'') ) self.write_function_details_entry(out, var_doc, descr, var_doc.value.callgraph_uid, rtype, rdescr, arg_descrs, div_class) # Properties elif isinstance(var_doc.value, PropertyDoc): prop_doc = var_doc.value accessors = [ (name, self.property_accessor_to_html(val_doc, prop_doc), self.summary(val_doc)) for (name, val_doc) in [('Get', prop_doc.fget), ('Set', prop_doc.fset), ('Delete', prop_doc.fdel)] if val_doc not in (None, UNKNOWN) and val_doc.pyval is not None ] self.write_property_details_entry(out, var_doc, descr, accessors, div_class) # Variables else: self.write_variable_details_entry(out, var_doc, descr, div_class) def labelled_list_item(self, lhs, rhs): # If the RHS starts with a paragraph, then move the # paragraph-start tag to the beginning of the lhs instead (so # there won't be a line break after the '-'). m = re.match(r'^]+)?>', rhs) if m: lhs = m.group() + lhs rhs = rhs[m.end():] if rhs: return '
  • %s - %s
  • ' % (lhs, rhs) else: return '
  • %s
  • ' % (lhs,) def property_accessor_to_html(self, val_doc, context=None): if val_doc not in (None, UNKNOWN): if isinstance(val_doc, RoutineDoc): return self.function_signature(val_doc, is_summary=True, link_name=True, context=context) elif isinstance(val_doc, GenericValueDoc): return self.pprint_value(val_doc) else: return self.href(val_doc, context=context) else: return '??' def arg_name_to_html(self, func_doc, arg_name): """ A helper function used to format an argument name, for use in the argument description list under a routine's details entry. This just wraps strong & code tags around the arg name; and if the arg name is associated with a type, then adds it parenthetically after the name. """ s = '%s' % arg_name if arg_name in func_doc.arg_types: typ = func_doc.arg_types[arg_name] typ_html = self.docstring_to_html(typ, func_doc, 10) s += " (%s)" % typ_html return s write_function_details_entry = compile_template( ''' write_function_details_entry(self, out, var_doc, descr, callgraph, \ rtype, rdescr, arg_descrs, div_class) ''', # /------------------------- Template -------------------------\ ''' >>> func_doc = var_doc.value >>> self.write_table_header(out, "details")

    $self.function_signature(var_doc)$ >>> if var_doc.name in self.SPECIAL_METHODS:
    ($self.SPECIAL_METHODS[var_doc.name]$) >>> #endif >>> if isinstance(func_doc, ClassMethodDoc):
    Class Method >>> #endif >>> if isinstance(func_doc, StaticMethodDoc):
    Static Method >>> #endif

    $self.pysrc_link(func_doc)$  $self.callgraph_link(callgraph)$
    $self.render_callgraph(callgraph)$ $descr$
    >>> # === parameters === >>> if arg_descrs:
    Parameters:
      >>> for lhs, rhs in arg_descrs: $self.labelled_list_item(lhs, rhs)$ >>> #endfor
    >>> #endif >>> # === return type === >>> if rdescr and rtype:
    Returns: $rtype$
    $rdescr$
    >>> elif rdescr:
    Returns:
    $rdescr$
    >>> elif rtype:
    Returns: $rtype$
    >>> #endif >>> # === decorators === >>> if func_doc.decorators not in (None, UNKNOWN): >>> # (staticmethod & classmethod are already shown, above) >>> decos = filter(lambda deco: >>> not ((deco=="staticmethod" and >>> isinstance(func_doc, StaticMethodDoc)) or >>> (deco=="classmethod" and >>> isinstance(func_doc, ClassMethodDoc))), >>> func_doc.decorators) >>> else: >>> decos = None >>> #endif >>> if decos:
    Decorators:
      >>> for deco in decos:
    • @$deco$
    • >>> #endfor
    >>> #endif >>> # === exceptions === >>> if func_doc.exception_descrs not in (None, UNKNOWN, (), []):
    Raises:
      >>> for name, descr in func_doc.exception_descrs: >>> exc_name = self.docindex.find(name, func_doc) >>> if exc_name is not None: >>> name = self.href(exc_name, label=str(name)) >>> #endif $self.labelled_list_item( "" + str(name) + "", self.docstring_to_html(descr, func_doc, 8))$ >>> #endfor
    >>> #endif >>> # === overrides === >>> if var_doc.overrides not in (None, UNKNOWN):
    Overrides: >>> # Avoid passing GenericValueDoc to href() >>> if isinstance(var_doc.overrides.value, RoutineDoc): $self.href(var_doc.overrides.value, context=var_doc)$ >>> else: >>> # In this case, a less interesting label is generated. $self.href(var_doc.overrides, context=var_doc)$ >>> #endif >>> if (func_doc.docstring in (None, UNKNOWN) and >>> var_doc.overrides.value.docstring not in (None, UNKNOWN)):
    (inherited documentation)
    >>> #endif >>> #endif
    >>> # === metadata === >>> self.write_standard_fields(out, func_doc)
    ''') # \------------------------------------------------------------/ # Names for the __special__ methods. SPECIAL_METHODS ={ '__init__': 'Constructor', '__del__': 'Destructor', '__add__': 'Addition operator', '__sub__': 'Subtraction operator', '__and__': 'And operator', '__or__': 'Or operator', '__xor__': 'Exclusive-Or operator', '__repr__': 'Representation operator', '__call__': 'Call operator', '__getattr__': 'Qualification operator', '__getitem__': 'Indexing operator', '__setitem__': 'Index assignment operator', '__delitem__': 'Index deletion operator', '__delslice__': 'Slice deletion operator', '__setslice__': 'Slice assignment operator', '__getslice__': 'Slicling operator', '__len__': 'Length operator', '__cmp__': 'Comparison operator', '__eq__': 'Equality operator', '__in__': 'Containership operator', '__gt__': 'Greater-than operator', '__lt__': 'Less-than operator', '__ge__': 'Greater-than-or-equals operator', '__le__': 'Less-than-or-equals operator', '__radd__': 'Right-side addition operator', '__hash__': 'Hashing function', '__contains__': 'In operator', '__nonzero__': 'Boolean test operator', '__str__': 'Informal representation operator', } write_property_details_entry = compile_template( ''' write_property_details_entry(self, out, var_doc, descr, \ accessors, div_class) ''', # /------------------------- Template -------------------------\ ''' >>> prop_doc = var_doc.value >>> self.write_table_header(out, "details")

    $var_doc.name$

    $descr$
    >>> for (name, val, summary) in accessors:
    $name$ Method:
    $val$ >>> if summary: - $summary$ >>> #endif
    >>> #endfor >>> if prop_doc.type_descr not in (None, UNKNOWN):
    Type:
    $self.type_descr(var_doc, indent=6)$
    >>> #endif
    >>> self.write_standard_fields(out, prop_doc)
    ''') # \------------------------------------------------------------/ write_variable_details_entry = compile_template( ''' write_variable_details_entry(self, out, var_doc, descr, div_class) ''', # /------------------------- Template -------------------------\ ''' >>> self.write_table_header(out, "details")

    $var_doc.name$

    $descr$
    >>> if var_doc.type_descr not in (None, UNKNOWN):
    Type:
    $self.type_descr(var_doc, indent=6)$
    >>> #endif
    >>> self.write_standard_fields(out, var_doc) >>> if var_doc.value is not UNKNOWN:
    Value:
    $self.pprint_value(var_doc.value)$
    >>> #endif
    ''') # \------------------------------------------------------------/ def variable_tooltip(self, var_doc): if var_doc.value in (None, UNKNOWN): return '' s = var_doc.value.pyval_repr().to_plaintext(None) if len(s) > self._variable_tooltip_linelen: s = s[:self._variable_tooltip_linelen-3]+'...' return ' title="%s"' % plaintext_to_html(s) def pprint_value(self, val_doc): if val_doc is UNKNOWN: return '??' elif isinstance(val_doc, GenericValueDoc): return ('
    \n' +
                        val_doc.pyval_repr().to_html(None) +
                        '\n
    \n') else: return self.href(val_doc) #//////////////////////////////////////////////////////////// #{ Base Tree #//////////////////////////////////////////////////////////// def base_tree(self, doc, width=None, postfix='', context=None): """ @return: The HTML code for a class's base tree. The tree is drawn 'upside-down' and right justified, to allow for multiple inheritance. @rtype: C{string} """ if context is None: context = doc.defining_module if width == None: width = self.find_tree_width(doc, context) if isinstance(doc, ClassDoc) and doc.bases != UNKNOWN: bases = doc.bases else: bases = [] if postfix == '': # [XX] use var name instead of canonical name? s = (' '*(width-2) + ''+ self.contextual_label(doc, context)+'\n') else: s = '' for i in range(len(bases)-1, -1, -1): base = bases[i] label = self.contextual_label(base, context) s = (' '*(width-4-len(label)) + self.href(base, label) +' --+'+postfix+'\n' + ' '*(width-4) + ' |'+postfix+'\n' + s) if i != 0: s = (self.base_tree(base, width-4, ' |'+postfix, context)+s) else: s = (self.base_tree(base, width-4, ' '+postfix, context)+s) return s def find_tree_width(self, doc, context): """ Helper function for L{base_tree}. @return: The width of a base tree, when drawn right-justified. This is used by L{base_tree} to determine how far to indent lines of the base tree. @rtype: C{int} """ if not isinstance(doc, ClassDoc): return 2 if doc.bases == UNKNOWN: return 2 width = 2 for base in doc.bases: width = max(width, len(self.contextual_label(base, context))+4, self.find_tree_width(base, context)+4) return width def contextual_label(self, doc, context): """ Return the label for C{doc} to be shown in C{context}. """ if doc.canonical_name is None: if doc.parse_repr is not None: return doc.parse_repr else: return '??' else: if context is UNKNOWN: return str(doc.canonical_name) else: context_name = context.canonical_name return str(doc.canonical_name.contextualize(context_name)) #//////////////////////////////////////////////////////////// #{ Function Signatures #//////////////////////////////////////////////////////////// def function_signature(self, api_doc, is_summary=False, link_name=False, anchor=False, context=None): """Render a function signature in HTML. @param api_doc: The object whose name is to be rendered. If a C{VariableDoc}, its C{value} should be a C{RoutineDoc} @type api_doc: L{VariableDoc} or L{RoutineDoc} @param is_summary: True if the fuction is to be rendered in the summary. type css_class: C{bool} @param link_name: If True, the name is a link to the object anchor. @type link_name: C{bool} @param anchor: If True, the name is the object anchor. @type anchor: C{bool} @param context: If set, represent the function name from this context. Only useful when C{api_doc} is a L{RoutineDoc}. @type context: L{DottedName} @return: The HTML code for the object. @rtype: C{str} """ if is_summary: css_class = 'summary-sig' else: css_class = 'sig' # [XX] clean this up! if isinstance(api_doc, VariableDoc): func_doc = api_doc.value # This should never happen, but just in case: if api_doc.value in (None, UNKNOWN): return (('%s'+ '(...)') % (css_class, css_class, api_doc.name)) # Get the function's name. name = self.summary_name(api_doc, css_class=css_class+'-name', link_name=link_name, anchor=anchor) else: func_doc = api_doc name = self.href(api_doc, css_class=css_class+'-name', context=context) if func_doc.posargs == UNKNOWN: args = ['...'] else: args = [self.func_arg(n, d, css_class) for (n, d) in zip(func_doc.posargs, func_doc.posarg_defaults)] if func_doc.vararg not in (None, UNKNOWN): if func_doc.vararg == '...': args.append('...' % css_class) else: args.append('*%s' % (css_class, func_doc.vararg)) if func_doc.kwarg not in (None, UNKNOWN): args.append('**%s' % (css_class, func_doc.kwarg)) return ('%s(%s)' % (css_class, name, ',\n '.join(args))) def summary_name(self, api_doc, css_class='summary-name', link_name=False, anchor=False): """Render an object name in HTML. @param api_doc: The object whose name is to be rendered @type api_doc: L{APIDoc} @param css_class: The CSS class to assign to the rendered name type css_class: C{str} @param link_name: If True, the name is a link to the object anchor. @type link_name: C{bool} @param anchor: If True, the name is the object anchor. @type anchor: C{bool} @return: The HTML code for the object. @rtype: C{str} """ if anchor: rv = '' % api_doc.name else: rv = '' if link_name: rv += self.href(api_doc, css_class=css_class) else: rv += '%s' % (css_class, api_doc.name) return rv # [xx] tuple args??? def func_arg(self, name, default, css_class): name = self._arg_name(name) s = '%s' % (css_class, name) if default is not None: s += ('=%s' % (css_class, default.summary_pyval_repr().to_html(None))) return s def _arg_name(self, arg): if isinstance(arg, basestring): return arg elif len(arg) == 1: return '(%s,)' % self._arg_name(arg[0]) else: return '(%s)' % (', '.join([self._arg_name(a) for a in arg])) #//////////////////////////////////////////////////////////// #{ Import Lists #//////////////////////////////////////////////////////////// def write_imports(self, out, doc): assert isinstance(doc, NamespaceDoc) imports = doc.select_variables(imported=True, public=self._public_filter) if not imports: return out('

    ') out('Imports:\n ') out(',\n '.join([self._import(v, doc) for v in imports])) out('\n


    \n') def _import(self, var_doc, context): if var_doc.imported_from not in (None, UNKNOWN): return self.href(var_doc.imported_from, var_doc.name, context=context, tooltip='%s' % var_doc.imported_from) elif (var_doc.value not in (None, UNKNOWN) and not isinstance(var_doc.value, GenericValueDoc)): return self.href(var_doc.value, var_doc.name, context=context, tooltip='%s' % var_doc.value.canonical_name) else: return plaintext_to_html(var_doc.name) #//////////////////////////////////////////////////////////// #{ Function Attributes #//////////////////////////////////////////////////////////// #//////////////////////////////////////////////////////////// #{ Module Trees #//////////////////////////////////////////////////////////// def write_module_list(self, out, doc): if len(doc.submodules) == 0: return self.write_table_header(out, "summary", "Submodules") for group_name in doc.group_names(): if not doc.submodule_groups[group_name]: continue if group_name: self.write_group_header(out, group_name) out(' \n' '
      \n') for submodule in doc.submodule_groups[group_name]: self.write_module_tree_item(out, submodule, package=doc) out('
    \n') out(self.TABLE_FOOTER+'\n
    \n') def write_module_tree_item(self, out, doc, package=None): # If it's a private variable, then mark its
  • . var = package and package.variables.get(doc.canonical_name[-1]) priv = ((var is not None and var.is_public is False) or (var is None and doc.canonical_name[-1].startswith('_'))) out(' %s' % (priv and ' class="private"' or '', self.href(doc))) if doc.summary not in (None, UNKNOWN): out(': '+ self.description(doc.summary, doc, 8)+'') if doc.submodules != UNKNOWN and doc.submodules: if priv: out('\n
      \n') else: out('\n
        \n') for submodule in doc.submodules: self.write_module_tree_item(out, submodule, package=doc) out('
      \n') out(' \n') #//////////////////////////////////////////////////////////// #{ Class trees #//////////////////////////////////////////////////////////// write_class_tree_item = compile_template( ''' write_class_tree_item(self, out, doc, class_set) ''', # /------------------------- Template -------------------------\ ''' >>> if doc.summary in (None, UNKNOWN):
    • $self.href(doc)$ >>> else:
    • $self.href(doc)$: $self.description(doc.summary, doc, 8)$ >>> # endif >>> if doc.subclasses:
        >>> for subclass in sorted(set(doc.subclasses), key=lambda c:c.canonical_name[-1]): >>> if subclass in class_set: >>> self.write_class_tree_item(out, subclass, class_set) >>> #endif >>> #endfor
      >>> #endif
    • ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ Standard Fields #//////////////////////////////////////////////////////////// def write_standard_fields(self, out, doc): """ Write HTML code containing descriptions of any standard markup fields that are defined by the given L{APIDoc} object (such as C{@author} and C{@todo} fields). @param doc: The L{APIDoc} object containing the API documentation for the object whose standard markup fields should be described. """ fields = [] field_values = {} for (field, arg, descr) in doc.metadata: if field not in field_values: fields.append(field) if field.takes_arg: subfields = field_values.setdefault(field,{}) subfields.setdefault(arg,[]).append(descr) else: field_values.setdefault(field,[]).append(descr) if not fields: return out('
      ') for field in fields: if field.takes_arg: for arg, descrs in field_values[field].items(): self.write_standard_field(out, doc, field, descrs, arg) else: self.write_standard_field(out, doc, field, field_values[field]) out('
      ') write_standard_field = compile_template( """ write_standard_field(self, out, doc, field, descrs, arg='') """, # /------------------------- Template -------------------------\ ''' >>> if arg: arglabel = " (%s)" % arg >>> else: arglabel = "" >>> if len(descrs) == 1:

      $field.singular+arglabel$: $self.description(descrs[0], doc, 8)$

      >>> elif field.short:
      $field.plural+arglabel$:
      >>> for descr in descrs[:-1]: $self.description(descr, doc, 10)$, >>> # end for $self.description(descrs[-1], doc, 10)$
      >>> else: $field.plural+arglabel$:
        >>> for descr in descrs:
      • $self.description(descr, doc, 8)$
      • >>> # end for
      >>> # end else >>> # end for ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ Index generation #//////////////////////////////////////////////////////////// #: A list of metadata indices that should be generated. Each #: entry in this list is a tuple C{(tag, label, short_label)}, #: where C{tag} is the cannonical tag of a metadata field; #: C{label} is a label for the index page; and C{short_label} #: is a shorter label, used in the index selector. METADATA_INDICES = [('bug', 'Bug List', 'Bugs'), ('todo', 'To Do List', 'To Do'), ('change', 'Change Log', 'Changes'), ('deprecated', 'Deprecation List', 'Deprecations'), ('since', 'Introductions List', 'Introductions'), ] def build_identifier_index(self): items = [] for doc in self.indexed_docs: name = plaintext_to_html(doc.canonical_name[-1]) if isinstance(doc, RoutineDoc): name += '()' url = self.url(doc) if not url: continue container = self.docindex.container(doc) items.append( (name, url, container) ) return sorted(items, key=lambda v:v[0].lower()) def _group_by_letter(self, items): """Preserves sort order of the input.""" index = {} for item in items: first_letter = item[0][0].upper() if not ("A" <= first_letter <= "Z"): first_letter = '_' index.setdefault(first_letter, []).append(item) return index def build_term_index(self): items = [] for doc in self.indexed_docs: url = self.url(doc) items += self._terms_from_docstring(url, doc, doc.descr) for (field, arg, descr) in doc.metadata: items += self._terms_from_docstring(url, doc, descr) if hasattr(doc, 'type_descr'): items += self._terms_from_docstring(url, doc, doc.type_descr) if hasattr(doc, 'return_descr'): items += self._terms_from_docstring(url, doc, doc.return_descr) if hasattr(doc, 'return_type'): items += self._terms_from_docstring(url, doc, doc.return_type) return sorted(items, key=lambda v:v[0].lower()) def _terms_from_docstring(self, base_url, container, parsed_docstring): if parsed_docstring in (None, UNKNOWN): return [] terms = [] # Strip any existing anchor off: base_url = re.sub('#.*', '', '%s' % (base_url,)) for term in parsed_docstring.index_terms(): anchor = self._term_index_to_anchor(term) url = '%s#%s' % (base_url, anchor) terms.append( (term.to_plaintext(None), url, container) ) return terms def build_metadata_index(self, field_name): # Build the index. index = {} for doc in self.indexed_docs: if (not self._show_private and self._doc_or_ancestor_is_private(doc)): continue descrs = {} if doc.metadata is not UNKNOWN: for (field, arg, descr) in doc.metadata: if field.tags[0] == field_name: descrs.setdefault(arg, []).append(descr) for (arg, descr_list) in descrs.iteritems(): index.setdefault(arg, []).append( (doc, descr_list) ) return index def _term_index_to_anchor(self, term): """ Given the name of an inline index item, construct a URI anchor. These anchors are used to create links from the index page to each index item. """ # Include "-" so we don't accidentally collide with the name # of a python identifier. s = re.sub(r'\s\s+', '-', term.to_plaintext(None)) return "index-"+re.sub("[^a-zA-Z0-9]", "_", s) #//////////////////////////////////////////////////////////// #{ Redirect page #//////////////////////////////////////////////////////////// def write_redirect_page(self, out): """ Build the auto-redirect page, which translates dotted names to URLs using javascript. When the user visits , they will automatically get redirected to the page for the object with the given fully-qualified dotted name. E.g., for epydoc, redirects the user to . """ # Construct a list of all the module & class pages that we're # documenting. The redirect_url javascript will scan through # this list, looking for a page name that matches the # requested dotted name. pages = (['%s-m' % val_doc.canonical_name for val_doc in self.module_list] + ['%s-c' % val_doc.canonical_name for val_doc in self.class_list]) # Sort the pages from longest to shortest. This ensures that # we find e.g. "x.y.z" in the list before "x.y". pages = sorted(pages, key=lambda p:-len(p)) # Write the redirect page. self._write_redirect_page(out, pages) _write_redirect_page = compile_template( ''' _write_redirect_page(self, out, pages) ''', # /------------------------- Template -------------------------\ ''' Epydoc Redirect Page

      Epydoc Auto-redirect page

      When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

       

      ''') # \------------------------------------------------------------/ #//////////////////////////////////////////////////////////// #{ URLs list #//////////////////////////////////////////////////////////// def write_api_list(self, out): """ Write a list of mapping name->url for all the documented objects. """ # Construct a list of all the module & class pages that we're # documenting. The redirect_url javascript will scan through # this list, looking for a page name that matches the # requested dotted name. skip = (ModuleDoc, ClassDoc, type(UNKNOWN)) for val_doc in self.module_list: self.write_url_record(out, val_doc) for var in val_doc.variables.itervalues(): if not isinstance(var.value, skip): self.write_url_record(out, var) for val_doc in self.class_list: self.write_url_record(out, val_doc) for var in val_doc.variables.itervalues(): self.write_url_record(out, var) def write_url_record(self, out, obj): url = self.url(obj) if url is not None: out("%s\t%s\n" % (obj.canonical_name, url)) #//////////////////////////////////////////////////////////// #{ Helper functions #//////////////////////////////////////////////////////////// def _val_is_public(self, valdoc): """Make a best-guess as to whether the given class is public.""" container = self.docindex.container(valdoc) if isinstance(container, NamespaceDoc): for vardoc in container.variables.values(): if vardoc in (UNKNOWN, None): continue if vardoc.value is valdoc: return vardoc.is_public return True # [XX] Is it worth-while to pull the anchor tricks that I do here? # Or should I just live with the fact that show/hide private moves # stuff around? write_table_header = compile_template( ''' write_table_header(self, out, css_class, heading=None, \ private_link=True, colspan=2) ''', # /------------------------- Template -------------------------\ ''' >>> if heading is not None: >>> anchor = "section-%s" % re.sub("\W", "", heading) >>> #endif >>> if heading is not None: >>> if private_link and self._show_private: >>> else: >>> #endif >>> #endif ''') # \------------------------------------------------------------/ TABLE_FOOTER = '
      $heading$ [hide private]
      $heading$
      \n' PRIVATE_LINK = ''' [hide private] '''.strip() write_group_header = compile_template( ''' write_group_header(self, out, group, tr_class='') ''', # /------------------------- Template -------------------------\ '''     $group$ ''') # \------------------------------------------------------------/ _url_cache = {} def url(self, obj): """ Return the URL for the given object, which can be a C{VariableDoc}, a C{ValueDoc}, or a C{DottedName}. """ cached_url = self._url_cache.get(id(obj)) if cached_url is not None: return cached_url else: url = self._url_cache[id(obj)] = self._url(obj) return url def _url(self, obj): """ Internal helper for L{url}. """ # Module: -module.html if isinstance(obj, ModuleDoc): if obj not in self.module_set: return None return urllib.quote('%s'%obj.canonical_name) + '-module.html' # Class: -class.html elif isinstance(obj, ClassDoc): if obj not in self.class_set: return None return urllib.quote('%s'%obj.canonical_name) + '-class.html' # Variable elif isinstance(obj, VariableDoc): val_doc = obj.value if isinstance(val_doc, (ModuleDoc, ClassDoc)): return self.url(val_doc) elif obj.container in (None, UNKNOWN): if val_doc in (None, UNKNOWN): return None return self.url(val_doc) elif obj.is_imported == True: if obj.imported_from is not UNKNOWN: return self.url(obj.imported_from) else: return None else: container_url = self.url(obj.container) if container_url is None: return None return '%s#%s' % (container_url, urllib.quote('%s'%obj.name)) # Value (other than module or class) elif isinstance(obj, ValueDoc): container = self.docindex.container(obj) if container is None: return None # We couldn't find it! else: container_url = self.url(container) if container_url is None: return None anchor = urllib.quote('%s'%obj.canonical_name[-1]) return '%s#%s' % (container_url, anchor) # Dotted name: look up the corresponding APIDoc elif isinstance(obj, DottedName): val_doc = self.docindex.get_valdoc(obj) if val_doc is None: return None return self.url(val_doc) # Special pages: elif obj == 'indices': return 'identifier-index.html' elif obj == 'help': return 'help.html' elif obj == 'trees': return self._trees_url else: raise ValueError, "Don't know what to do with %r" % obj def pysrc_link(self, api_doc): if not self._incl_sourcecode: return '' url = self.pysrc_url(api_doc) if url is not None: return ('source ' 'code' % url) else: return '' def pysrc_url(self, api_doc): if isinstance(api_doc, VariableDoc): if api_doc.value not in (None, UNKNOWN): return pysrc_url(api_doc.value) else: return None elif isinstance(api_doc, ModuleDoc): if api_doc in self.modules_with_sourcecode: return ('%s-pysrc.html' % urllib.quote('%s' % api_doc.canonical_name)) else: return None else: module = api_doc.defining_module if module == UNKNOWN: return None module_pysrc_url = self.pysrc_url(module) if module_pysrc_url is None: return None module_name = module.canonical_name if not module_name.dominates(api_doc.canonical_name, True): log.debug('%r is in %r but name does not dominate' % (api_doc, module)) return module_pysrc_url mname_len = len(module.canonical_name) anchor = '%s' % api_doc.canonical_name[mname_len:] return '%s#%s' % (module_pysrc_url, urllib.quote(anchor)) # We didn't find it: return None # [xx] add code to automatically do wrapping or the like? def href(self, target, label=None, css_class=None, context=None, tooltip=None): """ Return the HTML code for an HREF link to the given target (which can be a C{VariableDoc}, a C{ValueDoc}, or a C{DottedName}. If a C{NamespaceDoc} C{context} is specified, the target label is contextualized to it. """ assert isinstance(target, (APIDoc, DottedName)) # Pick a label, if none was given. if label is None: if isinstance(target, VariableDoc): label = target.name elif (isinstance(target, ValueDoc) and target.canonical_name is not UNKNOWN): label = target.canonical_name elif isinstance(target, DottedName): label = target elif isinstance(target, GenericValueDoc): raise ValueError("href() should not be called with " "GenericValueDoc objects (perhaps you " "meant to use the containing variable?)") else: raise ValueError("Unable to find a label for %r" % target) if context is not None and isinstance(label, DottedName): label = label.contextualize(context.canonical_name.container()) label = plaintext_to_html(str(label)) # Munge names for scripts & unreachable values if label.startswith('script-'): label = label[7:] + ' (script)' if label.startswith('??'): label = 'unreachable' + label[2:] label = re.sub(r'-\d+$', '', label) # Get the url for the target. url = self.url(target) if url is None: if tooltip: return '%s' % (tooltip, label) else: return label # Construct a string for the class attribute. if css_class is None: css = '' else: css = ' class="%s"' % css_class onclick = '' if ((isinstance(target, VariableDoc) and not target.is_public) or (isinstance(target, ValueDoc) and not isinstance(target, GenericValueDoc) and not self._val_is_public(target))): onclick = ' onclick="show_private();"' if tooltip: tooltip = ' title="%s"' % tooltip else: tooltip = '' return '%s' % (url, css, onclick, tooltip, label) def _attr_to_html(self, attr, api_doc, indent): if api_doc in (None, UNKNOWN): return '' pds = getattr(api_doc, attr, None) # pds = ParsedDocstring. if pds not in (None, UNKNOWN): return self.docstring_to_html(pds, api_doc, indent) elif isinstance(api_doc, VariableDoc): return self._attr_to_html(attr, api_doc.value, indent) def summary(self, api_doc, indent=0): return self._attr_to_html('summary', api_doc, indent) def descr(self, api_doc, indent=0): return self._attr_to_html('descr', api_doc, indent) def type_descr(self, api_doc, indent=0): return self._attr_to_html('type_descr', api_doc, indent) def return_type(self, api_doc, indent=0): return self._attr_to_html('return_type', api_doc, indent) def return_descr(self, api_doc, indent=0): return self._attr_to_html('return_descr', api_doc, indent) def docstring_to_html(self, parsed_docstring, where=None, indent=0): if parsed_docstring in (None, UNKNOWN): return '' linker = _HTMLDocstringLinker(self, where) s = parsed_docstring.to_html(linker, indent=indent, directory=self._directory, docindex=self.docindex, context=where).strip() if self._mark_docstrings: s = '%s' % s return s def description(self, parsed_docstring, where=None, indent=0): assert isinstance(where, (APIDoc, type(None))) if parsed_docstring in (None, UNKNOWN): return '' linker = _HTMLDocstringLinker(self, where) descr = parsed_docstring.to_html(linker, indent=indent, directory=self._directory, docindex=self.docindex, context=where).strip() if descr == '': return ' ' return descr # [xx] Should this be defined by the APIDoc classes themselves?? def doc_kind(self, doc): if isinstance(doc, ModuleDoc) and doc.is_package == True: return 'Package' elif (isinstance(doc, ModuleDoc) and doc.canonical_name[0].startswith('script')): return 'Script' elif isinstance(doc, ModuleDoc): return 'Module' elif isinstance(doc, ClassDoc): return 'Class' elif isinstance(doc, ClassMethodDoc): return 'Class Method' elif isinstance(doc, StaticMethodDoc): return 'Static Method' elif isinstance(doc, RoutineDoc): if isinstance(self.docindex.container(doc), ClassDoc): return 'Method' else: return 'Function' else: return 'Variable' def _doc_or_ancestor_is_private(self, api_doc): name = api_doc.canonical_name for i in range(len(name), 0, -1): # Is it (or an ancestor) a private var? var_doc = self.docindex.get_vardoc(name[:i]) if var_doc is not None and var_doc.is_public == False: return True # Is it (or an ancestor) a private module? val_doc = self.docindex.get_valdoc(name[:i]) if (val_doc is not None and isinstance(val_doc, ModuleDoc) and val_doc.canonical_name[-1].startswith('_')): return True return False def _private_subclasses(self, class_doc): """Return a list of all subclasses of the given class that are private, as determined by L{_val_is_private}. Recursive subclasses are included in this list.""" queue = [class_doc] private = set() for cls in queue: if (isinstance(cls, ClassDoc) and cls.subclasses not in (None, UNKNOWN)): queue.extend(cls.subclasses) private.update([c for c in cls.subclasses if not self._val_is_public(c)]) return private class _HTMLDocstringLinker(epydoc.markup.DocstringLinker): def __init__(self, htmlwriter, container): self.htmlwriter = htmlwriter self.docindex = htmlwriter.docindex self.container = container def translate_indexterm(self, indexterm): key = self.htmlwriter._term_index_to_anchor(indexterm) return ('%s' % (key, indexterm.to_html(self))) def translate_identifier_xref(self, identifier, label=None): # Pick a label for this xref. if label is None: label = plaintext_to_html(identifier) # Find the APIDoc for it (if it's available). doc = self.docindex.find(identifier, self.container) # If we didn't find a target, then try checking in the contexts # of the ancestor classes. if doc is None and isinstance(self.container, RoutineDoc): container = self.docindex.get_vardoc( self.container.canonical_name) while (doc is None and container not in (None, UNKNOWN) and container.overrides not in (None, UNKNOWN)): container = container.overrides doc = self.docindex.find(identifier, container) # Translate it into HTML. if doc is None: self._failed_xref(identifier) return '%s' % label else: return self.htmlwriter.href(doc, label, 'link') # [xx] Should this be added to the DocstringLinker interface??? # Currently, this is *only* used by dotgraph. def url_for(self, identifier): if isinstance(identifier, (basestring, DottedName)): doc = self.docindex.find(identifier, self.container) if doc: return self.htmlwriter.url(doc) else: return None elif isinstance(identifier, APIDoc): return self.htmlwriter.url(identifier) doc = identifier else: raise TypeError('Expected string or APIDoc') def _failed_xref(self, identifier): """Add an identifier to the htmlwriter's failed crossreference list.""" # Don't count it as a failed xref if it's a parameter of the # current function. if (isinstance(self.container, RoutineDoc) and identifier in self.container.all_args()): return failed_xrefs = self.htmlwriter._failed_xrefs context = self.container.canonical_name failed_xrefs.setdefault(identifier,{})[context] = 1 epydoc-3.0.1+dfsg/epydoc/docwriter/html_help.py0000644000175000017500000001727010654406440022022 0ustar pronovicpronovic# # epydoc.css: default help page # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: html_help.py 1239 2006-07-05 11:29:50Z edloper $ # """ Default help file for the HTML outputter (L{epydoc.docwriter.html}). @type HTML_HELP: C{string} @var HTML_HELP: The contents of the HTML body for the default help page. """ __docformat__ = 'epytext en' # Expects: {'this_project': name} HTML_HELP = '''

      API Documentation

      This document contains the API (Application Programming Interface) documentation for %(this_project)s. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

      Object Documentation

      Each Package Documentation page contains:

      • A description of the package.
      • A list of the modules and sub-packages contained by the package.
      • A summary of the classes defined by the package.
      • A summary of the functions defined by the package.
      • A summary of the variables defined by the package.
      • A detailed description of each function defined by the package.
      • A detailed description of each variable defined by the package.

      Each Module Documentation page contains:

      • A description of the module.
      • A summary of the classes defined by the module.
      • A summary of the functions defined by the module.
      • A summary of the variables defined by the module.
      • A detailed description of each function defined by the module.
      • A detailed description of each variable defined by the module.

      Each Class Documentation page contains:

      • A class inheritance diagram.
      • A list of known subclasses.
      • A description of the class.
      • A summary of the methods defined by the class.
      • A summary of the instance variables defined by the class.
      • A summary of the class (static) variables defined by the class.
      • A detailed description of each method defined by the class.
      • A detailed description of each instance variable defined by the class.
      • A detailed description of each class (static) variable defined by the class.

      Project Documentation

      The Trees page contains the module and class hierarchies:

      • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
      • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

      The Index page contains indices of terms and identifiers:

      • The term index lists every term indexed by any object\'s documentation. For each term, the index provides links to each place where the term is indexed.
      • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

      The Table of Contents

      The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

      Project
      Contents
      ...
      API
      Documentation
      Frame


      Module
      Contents
       
      ...
       

      The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

      The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

      The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

      The Navigation Bar

      A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

      Label Highlighted when... Links to...
      [Parent] (never highlighted) the parent of the current package
      [Package] viewing a package the package containing the current object
      [Module] viewing a module the module containing the current object
      [Class] viewing a class the class containing the current object
      [Trees] viewing the trees page the trees page
      [Index] viewing the index page the index page
      [Help] viewing the help page the help page

      The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

      A timestamp below the bottom navigation bar indicates when each page was last updated.

      ''' epydoc-3.0.1+dfsg/epydoc/__init__.py0000644000175000017500000002221410750073536017600 0ustar pronovicpronovic# epydoc # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: __init__.py 1691 2008-01-30 17:11:09Z edloper $ """ Automatic Python reference documentation generator. Epydoc processes Python modules and docstrings to generate formatted API documentation, in the form of HTML pages. Epydoc can be used via a command-line interface (`epydoc.cli`) and a graphical interface (`epydoc.gui`). Both interfaces let the user specify a set of modules or other objects to document, and produce API documentation using the following steps: 1. Extract basic information about the specified objects, and objects that are related to them (such as the values defined by a module). This can be done via introspection, parsing, or both: * *Introspection* imports the objects, and examines them directly using Python's introspection mechanisms. * *Parsing* reads the Python source files that define the objects, and extracts information from those files. 2. Combine and process that information. * **Merging**: Merge the information obtained from introspection & parsing each object into a single structure. * **Linking**: Replace any \"pointers\" that were created for imported variables with the documentation that they point to. * **Naming**: Assign unique *canonical names* to each of the specified objects, and any related objects. * **Docstrings**: Parse the docstrings of each of the specified objects. * **Inheritance**: Add variables to classes for any values that they inherit from their base classes. 3. Generate output. Output can be generated in a variety of formats: * An HTML webpage. * A LaTeX document (which can be rendered as a PDF file) * A plaintext description. .. digraph:: Overview of epydoc's architecture :caption: The boxes represent steps in epydoc's processing chain. Arrows are annotated with the data classes used to communicate between steps. The lines along the right side mark what portions of the processing chain are initiated by build_doc_index() and cli(). Click on any item to see its documentation. /* Python module or value * * / \ | | V V | | introspect_docs() parse_docs() | | \ / | | V V | | merge_docs() | | | build_doc_index() cli() V | | link_imports() | | | | | V | | assign_canonical_names() | | | | | V | | parse_docstrings() | | | | | V | | inherit_docs() * | / | \ | V V V | HTMLWriter LaTeXWriter PlaintextWriter * */ ranksep = 0.1; node [shape="box", height="0", width="0"] { /* Task nodes */ node [fontcolor=\"#000060\"] introspect [label="Introspect value:\\nintrospect_docs()", href=""] parse [label="Parse source code:\\nparse_docs()", href=""] merge [label="Merge introspected & parsed docs:\\nmerge_docs()", href="", width="2.5"] link [label="Link imports:\\nlink_imports()", href="", width="2.5"] name [label="Assign names:\\nassign_canonical_names()", href="", width="2.5"] docstrings [label="Parse docstrings:\\nparse_docstring()", href="", width="2.5"] inheritance [label="Inherit docs from bases:\\ninherit_docs()", href="", width="2.5"] write_html [label="Write HTML output:\\nHTMLWriter", href=""] write_latex [label="Write LaTeX output:\\nLaTeXWriter", href=""] write_text [label="Write text output:\\nPlaintextWriter", href=""] } { /* Input & Output nodes */ node [fontcolor=\"#602000\", shape="plaintext"] input [label="Python module or value"] output [label="DocIndex", href=""] } { /* Graph edges */ edge [fontcolor=\"#602000\"] input -> introspect introspect -> merge [label="APIDoc", href=""] input -> parse parse -> merge [label="APIDoc", href=""] merge -> link [label=" DocIndex", href=""] link -> name [label=" DocIndex", href=""] name -> docstrings [label=" DocIndex", href=""] docstrings -> inheritance [label=" DocIndex", href=""] inheritance -> output output -> write_html output -> write_latex output -> write_text } { /* Task collections */ node [shape="circle",label="",width=.1,height=.1] edge [fontcolor="black", dir="none", fontcolor=\"#000060\"] l3 -> l4 [label=" epydoc.\\l docbuilder.\\l build_doc_index()", href=""] l1 -> l2 [label=" epydoc.\\l cli()", href=""] } { rank=same; l1 l3 input } { rank=same; l2 write_html } { rank=same; l4 output } Package Organization ==================== The epydoc package contains the following subpackages and modules: .. packagetree:: :style: UML The user interfaces are provided by the `gui` and `cli` modules. The `apidoc` module defines the basic data types used to record information about Python objects. The programmatic interface to epydoc is provided by `docbuilder`. Docstring markup parsing is handled by the `markup` package, and output generation is handled by the `docwriter` package. See the submodule list for more information about the submodules and subpackages. :group User Interface: gui, cli :group Basic Data Types: apidoc :group Documentation Generation: docbuilder, docintrospecter, docparser :group Docstring Processing: docstringparser, markup :group Output Generation: docwriter :group Completeness Checking: checker :group Miscellaneous: log, util, test, compat :author: `Edward Loper `__ :requires: Python 2.3+ :version: 3.0.1 :see: `The epydoc webpage `__ :see: `The epytext markup language manual `__ :todo: Create a better default top_page than trees.html. :todo: Fix trees.html to work when documenting non-top-level modules/packages :todo: Implement @include :todo: Optimize epytext :todo: More doctests :todo: When introspecting, limit how much introspection you do (eg, don't construct docs for imported modules' vars if it's not necessary) :bug: UserDict.* is interpreted as imported .. why?? :license: IBM Open Source License :copyright: |copy| 2006 Edward Loper :newfield contributor: Contributor, Contributors (Alphabetical Order) :contributor: `Glyph Lefkowitz `__ :contributor: `Edward Loper `__ :contributor: `Bruce Mitchener `__ :contributor: `Jeff O'Halloran `__ :contributor: `Simon Pamies `__ :contributor: `Christian Reis `__ :contributor: `Daniele Varrazzo `__ .. |copy| unicode:: 0xA9 .. copyright sign """ __docformat__ = 'restructuredtext en' __version__ = '3.0.1' """The version of epydoc""" __author__ = 'Edward Loper ' """The primary author of eypdoc""" __url__ = 'http://epydoc.sourceforge.net' """The URL for epydoc's homepage""" __license__ = 'IBM Open Source License' """The license governing the use and distribution of epydoc""" # [xx] this should probably be a private variable: DEBUG = False """True if debugging is turned on.""" # Changes needed for docs: # - document the method for deciding what's public/private # - epytext: fields are defined slightly differently (@group) # - new fields # - document __extra_epydoc_fields__ and @newfield # - Add a faq? # - @type a,b,c: ... # - new command line option: --command-line-order epydoc-3.0.1+dfsg/epydoc/test/0002755000175000017500000000000010750103105016431 5ustar pronovicpronovicepydoc-3.0.1+dfsg/epydoc/test/util.py0000644000175000017500000002100610654406437017776 0ustar pronovicpronovic# # epydoc -- Utility functions used by regression tests (*.doctest) # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: html.py 1420 2007-01-28 14:19:30Z dvarrazzo $ # """ Utility functions used by the regression tests (C{*.doctest}). """ __docformat__ = 'epytext en' import tempfile, re, os, os.path, textwrap, sys from epydoc.docbuilder import build_doc, build_doc_index from epydoc.docparser import parse_docs from epydoc.docintrospecter import introspect_docs from epydoc.apidoc import ClassDoc, RoutineDoc from epydoc.markup import ParsedDocstring from epydoc.docwriter.html import HTMLWriter ###################################################################### #{ Test Functions ###################################################################### def buildvaluedoc(s): """ This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses build_doc to build documentation, and returns it as a C{ValueDoc} object. """ tmp_dir = write_pystring_to_tmp_dir(s) val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py')) cleanup_tmp_dir(tmp_dir) return val_doc def runbuilder(s, attribs='', build=None, exclude=''): """ This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses build_doc to build documentation, and pretty prints the resulting ModuleDoc object. The C{attribs} argument specifies which attributes of the C{APIDoc}s should be displayed. The C{build} argument gives the name of a variable in the module whose documentation should be built, instead of bilding docs for the whole module. """ # Write it to a temp file. tmp_dir = write_pystring_to_tmp_dir(s) # Build it. val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py')) if build: val_doc = val_doc.variables[build].value # Display it. if isinstance(val_doc, ClassDoc): for val in val_doc.variables.values(): if isinstance(val.value, RoutineDoc): fun_to_plain(val.value) s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) s = re.sub(r"(filename = ).*", r"\1...", s) s = re.sub(r"(", r"\1...>", s) s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) print s # Clean up. cleanup_tmp_dir(tmp_dir) def runparser(s, attribs='', show=None, exclude=''): """ This test function takes a string containing the contents of a module, and writes it to a file, uses `parse_docs` to parse it, and pretty prints the resulting ModuleDoc object. The `attribs` argument specifies which attributes of the `APIDoc`s should be displayed. The `show` argument, if specifies, gives the name of the object in the module that should be displayed (but the whole module will always be inspected; this just selects what to display). """ # Write it to a temp file. tmp_dir = write_pystring_to_tmp_dir(s) # Parse it. val_doc = parse_docs(os.path.join(tmp_dir, 'epydoc_test.py')) if show is not None: for name in show.split('.'): if isinstance(val_doc, ClassDoc): val_doc = val_doc.local_variables[name].value else: val_doc = val_doc.variables[name].value # Display it. s = val_doc.pp(include=attribs.split(), exclude=exclude.split()) s = re.sub(r"filename = .*", "filename = ...", s) print s # Clean up. cleanup_tmp_dir(tmp_dir) def runintrospecter(s, attribs='', introspect=None, exclude=''): """ This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses C{introspect_docs} to introspect it, and pretty prints the resulting ModuleDoc object. The C{attribs} argument specifies which attributes of the C{APIDoc}s should be displayed. The C{introspect} argument gives the name of a variable in the module whose value should be introspected, instead of introspecting the whole module. """ # Write it to a temp file. tmp_dir = write_pystring_to_tmp_dir(s) # Import it. sys.path.insert(0, tmp_dir) if introspect is None: import epydoc_test as val else: exec("from epydoc_test import %s as val" % introspect) del sys.path[0] # Introspect it. val_doc = introspect_docs(val) # Display it. s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) s = re.sub(r"(filename = ).*", r"\1...", s) s = re.sub(r"(", r"\1...>", s) s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) print s # Clean up. cleanup_tmp_dir(tmp_dir) def print_warnings(): """ Register a logger that will print warnings & errors. """ from epydoc import log del log._loggers[:] log.register_logger(log.SimpleLogger(log.DOCSTRING_WARNING)) def testencoding(s, introspect=True, parse=True, debug=False): """ An end-to-end test for unicode encodings. This function takes a given string, writes it to a python file, and processes that file's documentation. It then generates HTML output from the documentation, extracts all docstrings from the generated HTML output, and displays them. (In order to extract & display all docstrings, it monkey-patches the HMTLwriter.docstring_to_html() method.)""" # Monkey-patch docstring_to_html original_docstring_to_html = HTMLWriter.docstring_to_html HTMLWriter.docstring_to_html = print_docstring_as_html # Write s to a temporary file. tmp_dir = tempfile.mkdtemp() path = os.path.join(tmp_dir, 'enc_test.py') out = open(path, 'w') out.write(textwrap.dedent(s)) out.close() # Build docs for it docindex = build_doc_index([path], introspect, parse) if docindex is None: return sys.modules.pop('enc_test', None) # Write html output. writer = HTMLWriter(docindex, mark_docstrings=True) writer.write(tmp_dir) for file in os.listdir(tmp_dir): os.unlink(os.path.join(tmp_dir,file)) os.rmdir(tmp_dir) # Restore the HTMLWriter class to its original state. HTMLWriter.docstring_to_html = original_docstring_to_html ###################################################################### #{ Helper Functions ###################################################################### def write_pystring_to_tmp_dir(s): tmp_dir = tempfile.mkdtemp() out = open(os.path.join(tmp_dir, 'epydoc_test.py'), 'w') out.write(textwrap.dedent(s)) out.close() return tmp_dir def cleanup_tmp_dir(tmp_dir): os.unlink(os.path.join(tmp_dir, 'epydoc_test.py')) try: os.unlink(os.path.join(tmp_dir, 'epydoc_test.pyc')) except OSError: pass os.rmdir(tmp_dir) sys.modules.pop('epydoc_test', None) def to_plain(docstring): """Conver a parsed docstring into plain text""" if isinstance(docstring, ParsedDocstring): docstring = docstring.to_plaintext(None) return docstring.rstrip() def fun_to_plain(val_doc): """Convert parsed docstrings in text from a RoutineDoc""" for k, v in val_doc.arg_types.items(): val_doc.arg_types[k] = to_plain(v) for i, (k, v) in enumerate(val_doc.arg_descrs): val_doc.arg_descrs[i] = (k, to_plain(v)) def print_docstring_as_html(self, parsed_docstring, *varargs, **kwargs): """ Convert the given parsed_docstring to HTML and print it. Ignore any other arguments. This function is used by L{testencoding} to monkey-patch the HTMLWriter class's docstring_to_html() method. """ s = parsed_docstring.to_html(None).strip() s = s.encode('ascii', 'xmlcharrefreplace') s = remove_surrogates(s) print s return '' def remove_surrogates(s): """ The following is a helper function, used to convert two-character surrogate sequences into single characters. This is needed because some systems create surrogates but others don't. """ pieces = re.split('(&#\d+;)', s) for i in range(3, len(pieces)-1, 2): if pieces[i-1] != '': continue high,low = int(pieces[i-2][2:-1]), int(pieces[i][2:-1]) if 0xd800 <= high <= 0xdbff and 0xdc00 <= low <= 0xdfff: pieces[i-2] = '&#%d;' % (((high&0x3ff)<<10) + (low&0x3ff) + 0x10000) pieces[i] = '' return ''.join(pieces) epydoc-3.0.1+dfsg/epydoc/test/__init__.py0000644000175000017500000000617610654406437020573 0ustar pronovicpronovic# epydoc -- Regression testing # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: __init__.py 1502 2007-02-14 08:38:44Z edloper $ """ Regression testing. """ __docformat__ = 'epytext en' import unittest, doctest, epydoc, os, os.path, re, sys def main(): try: doctest.register_optionflag except: print ("\n" "The regression test suite requires a more recent version of\n" "doctest (e.g., the version that ships with Python 2.4 or 2.5).\n" "Please place a new version of doctest on your path before \n" "running the test suite.\n") return PY24 = doctest.register_optionflag('PYTHON2.4') """Flag indicating that a doctest example requires Python 2.4+""" PY25 = doctest.register_optionflag('PYTHON2.5') """Flag indicating that a doctest example requires Python 2.5+""" class DocTestParser(doctest.DocTestParser): """ Custom doctest parser that adds support for two new flags +PYTHON2.4 and +PYTHON2.5. """ def parse(self, string, name=''): pieces = doctest.DocTestParser.parse(self, string, name) for i, val in enumerate(pieces): if (isinstance(val, doctest.Example) and ((val.options.get(PY24, False) and sys.version[:2] < (2,4)) or (val.options.get(PY25, False) and sys.version[:2] < (2,5)))): pieces[i] = doctest.Example('1', '1') return pieces # Turn on debugging. epydoc.DEBUG = True # Options for doctest: options = doctest.ELLIPSIS doctest.set_unittest_reportflags(doctest.REPORT_UDIFF) # Use a custom parser parser = DocTestParser() # Find all test cases. tests = [] testdir = os.path.join(os.path.split(__file__)[0]) if testdir == '': testdir = '.' for filename in os.listdir(testdir): if (filename.endswith('.doctest') and check_requirements(os.path.join(testdir, filename))): tests.append(doctest.DocFileSuite(filename, optionflags=options, parser=parser)) # Run all test cases. unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(tests)) def check_requirements(filename): """ Search for strings of the form:: [Require: ] If any are found, then try importing the module named . If the import fails, then return False. If all required modules are found, return True. (This includes the case where no requirements are listed.) """ s = open(filename).read() for m in re.finditer('(?mi)^[ ]*\:RequireModule:(.*)$', s): module = m.group(1).strip() try: __import__(module) except ImportError: print ('Skipping %r (required module %r not found)' % (os.path.split(filename)[-1], module)) return False return True if __name__=='__main__': main() epydoc-3.0.1+dfsg/epydoc/docparser.py0000644000175000017500000024414110747502234020026 0ustar pronovicpronovic# epydoc -- Source code parsing # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: docparser.py 1673 2008-01-29 05:42:58Z edloper $ """ Extract API documentation about python objects by parsing their source code. The function L{parse_docs()}, which provides the main interface of this module, reads and parses the Python source code for a module, and uses it to create an L{APIDoc} object containing the API documentation for the variables and values defined in that modules. Currently, C{parse_docs()} extracts documentation from the following source code constructions: - module docstring - import statements - class definition blocks - function definition blocks - assignment statements - simple assignment statements - assignment statements with multiple C{'='}s - assignment statements with unpacked left-hand sides - assignment statements that wrap a function in classmethod or staticmethod. - assignment to special variables __path__, __all__, and __docformat__. - delete statements C{parse_docs()} does not yet support the following source code constructions: - assignment statements that create properties By default, C{parse_docs()} will expore the contents of top-level C{try} and C{if} blocks. If desired, C{parse_docs()} can also be configured to explore the contents of C{while} and C{for} blocks. (See the configuration constants, below.) @todo: Make it possible to extend the functionality of C{parse_docs()}, by replacing process_line with a dispatch table that can be customized (similarly to C{docintrospector.register_introspector()}). """ __docformat__ = 'epytext en' ###################################################################### ## Imports ###################################################################### # Python source code parsing: import token, tokenize # Finding modules: import imp # File services: import os, os.path, sys # Unicode: import codecs # API documentation encoding: from epydoc.apidoc import * # For looking up the docs of builtins: import __builtin__, exceptions import epydoc.docintrospecter # Misc utility functions: from epydoc.util import * # Backwards compatibility from epydoc.compat import * ###################################################################### ## Doc Parser ###################################################################### class ParseError(Exception): """ An exception that is used to signify that C{docparser} encountered syntactically invalid Python code while processing a Python source file. """ _moduledoc_cache = {} """A cache of C{ModuleDoc}s that we've already created. C{_moduledoc_cache} is a dictionary mapping from filenames to C{ValueDoc} objects. @type: C{dict}""" #//////////////////////////////////////////////////////////// # Configuration Constants #//////////////////////////////////////////////////////////// #{ Configuration Constants: Control Flow PARSE_TRY_BLOCKS = True """Should the contents of C{try} blocks be examined?""" PARSE_EXCEPT_BLOCKS = True """Should the contents of C{except} blocks be examined?""" PARSE_FINALLY_BLOCKS = True """Should the contents of C{finally} blocks be examined?""" PARSE_IF_BLOCKS = True """Should the contents of C{if} blocks be examined?""" PARSE_ELSE_BLOCKS = True """Should the contents of C{else} and C{elif} blocks be examined?""" PARSE_WHILE_BLOCKS = False """Should the contents of C{while} blocks be examined?""" PARSE_FOR_BLOCKS = False """Should the contents of C{for} blocks be examined?""" #{ Configuration Constants: Imports IMPORT_HANDLING = 'link' """What should C{docparser} do when it encounters an import statement? - C{'link'}: Create variabledoc objects with imported_from pointers to the source object. - C{'parse'}: Parse the imported file, to find the actual documentation for the imported object. (This will fall back to the 'link' behavior if the imported file can't be parsed, e.g., if it's a builtin.) """ IMPORT_STAR_HANDLING = 'parse' """When C{docparser} encounters a C{'from M{m} import *'} statement, and is unable to parse C{M{m}} (either because L{IMPORT_HANDLING}=C{'link'}, or because parsing failed), how should it determine the list of identifiers expored by C{M{m}}? - C{'ignore'}: ignore the import statement, and don't create any new variables. - C{'parse'}: parse it to find a list of the identifiers that it exports. (This will fall back to the 'ignore' behavior if the imported file can't be parsed, e.g., if it's a builtin.) - C{'introspect'}: import the module and introspect it (using C{dir}) to find a list of the identifiers that it exports. (This will fall back to the 'ignore' behavior if the imported file can't be parsed, e.g., if it's a builtin.) """ DEFAULT_DECORATOR_BEHAVIOR = 'transparent' """When C{DocParse} encounters an unknown decorator, what should it do to the documentation of the decorated function? - C{'transparent'}: leave the function's documentation as-is. - C{'opaque'}: replace the function's documentation with an empty C{ValueDoc} object, reflecting the fact that we have no knowledge about what value the decorator returns. """ BASE_HANDLING = 'parse'#'link' """What should C{docparser} do when it encounters a base class that was imported from another module? - C{'link'}: Create a valuedoc with a C{proxy_for} pointer to the base class. - C{'parse'}: Parse the file containing the base class, to find the actual documentation for it. (This will fall back to the 'link' behavior if the imported file can't be parsed, e.g., if it's a builtin.) """ #{ Configuration Constants: Comment docstrings COMMENT_DOCSTRING_MARKER = '#:' """The prefix used to mark comments that contain attribute docstrings for variables.""" #{ Configuration Constants: Grouping START_GROUP_MARKER = '#{' """The prefix used to mark a comment that starts a group. This marker should be followed (on the same line) by the name of the group. Following a start-group comment, all variables defined at the same indentation level will be assigned to this group name, until the parser reaches the end of the file, a matching end-group comment, or another start-group comment at the same indentation level. """ END_GROUP_MARKER = '#}' """The prefix used to mark a comment that ends a group. See L{START_GROUP_MARKER}.""" #///////////////////////////////////////////////////////////////// #{ Module parser #///////////////////////////////////////////////////////////////// def parse_docs(filename=None, name=None, context=None, is_script=False): """ Generate the API documentation for a specified object by parsing Python source files, and return it as a L{ValueDoc}. The object to generate documentation for may be specified using the C{filename} parameter I{or} the C{name} parameter. (It is an error to specify both a filename and a name; or to specify neither a filename nor a name). @param filename: The name of the file that contains the python source code for a package, module, or script. If C{filename} is specified, then C{parse} will return a C{ModuleDoc} describing its contents. @param name: The fully-qualified python dotted name of any value (including packages, modules, classes, and functions). C{parse_docs()} will automatically figure out which module(s) it needs to parse in order to find the documentation for the specified object. @param context: The API documentation for the package that contains C{filename}. If no context is given, then C{filename} is assumed to contain a top-level module or package. It is an error to specify a C{context} if the C{name} argument is used. @rtype: L{ValueDoc} """ # Always introspect __builtins__ & exceptions (e.g., in case # they're used as base classes.) epydoc.docintrospecter.introspect_docs(__builtin__) epydoc.docintrospecter.introspect_docs(exceptions) # If our input is a python object name, then delegate to # _find(). if filename is None and name is not None: if context: raise ValueError("context should only be specified together " "with filename, not with name.") name = DottedName(name) val_doc = _find(name) if val_doc.canonical_name is UNKNOWN: val_doc.canonical_name = name return val_doc # If our input is a filename, then create a ModuleDoc for it, # and use process_file() to populate its attributes. elif filename is not None and name is None: # Use a python source version, if possible. if not is_script: try: filename = py_src_filename(filename) except ValueError, e: raise ImportError('%s' % e) # Check the cache, first. if filename in _moduledoc_cache: return _moduledoc_cache[filename] log.info("Parsing %s" % filename) # If the context wasn't provided, then check if the file is in # a package directory. If so, then update basedir & name to # contain the topmost package's directory and the fully # qualified name for this file. (This update assume the # default value of __path__ for the parent packages; if the # parent packages override their __path__s, then this can # cause us not to find the value.) if context is None and not is_script: basedir = os.path.split(filename)[0] name = os.path.splitext(os.path.split(filename)[1])[0] if name == '__init__': basedir, name = os.path.split(basedir) context = _parse_package(basedir) # Figure out the canonical name of the module we're parsing. if not is_script: module_name, is_pkg = _get_module_name(filename, context) else: module_name = DottedName(munge_script_name(filename)) is_pkg = False # Create a new ModuleDoc for the module, & add it to the cache. module_doc = ModuleDoc(canonical_name=module_name, variables={}, sort_spec=[], imports=[], filename=filename, package=context, is_package=is_pkg, submodules=[], docs_extracted_by='parser') module_doc.defining_module = module_doc _moduledoc_cache[filename] = module_doc # Set the module's __path__ to its default value. if is_pkg: module_doc.path = [os.path.split(module_doc.filename)[0]] # Add this module to the parent package's list of submodules. if context is not None: context.submodules.append(module_doc) # Tokenize & process the contents of the module's source file. try: process_file(module_doc) except tokenize.TokenError, e: msg, (srow, scol) = e.args raise ParseError('Error during parsing: %s ' '(%s, line %d, char %d)' % (msg, module_doc.filename, srow, scol)) except IndentationError, e: raise ParseError('Error during parsing: %s (%s)' % (e, module_doc.filename)) # Handle any special variables (__path__, __docformat__, etc.) handle_special_module_vars(module_doc) # Return the completed ModuleDoc return module_doc else: raise ValueError("Expected exactly one of the following " "arguments: name, filename") def _parse_package(package_dir): """ If the given directory is a package directory, then parse its __init__.py file (and the __init__.py files of all ancestor packages); and return its C{ModuleDoc}. """ if not is_package_dir(package_dir): return None parent_dir = os.path.split(package_dir)[0] parent_doc = _parse_package(parent_dir) package_file = os.path.join(package_dir, '__init__') return parse_docs(filename=package_file, context=parent_doc) # Special vars: # C{__docformat__}, C{__all__}, and C{__path__}. def handle_special_module_vars(module_doc): # If __docformat__ is defined, parse its value. toktree = _module_var_toktree(module_doc, '__docformat__') if toktree is not None: try: module_doc.docformat = parse_string(toktree) except: pass del module_doc.variables['__docformat__'] # If __all__ is defined, parse its value. toktree = _module_var_toktree(module_doc, '__all__') if toktree is not None: try: public_names = set(parse_string_list(toktree)) for name, var_doc in module_doc.variables.items(): if name in public_names: var_doc.is_public = True if not isinstance(var_doc, ModuleDoc): var_doc.is_imported = False else: var_doc.is_public = False except ParseError: # If we couldn't parse the list, give precedence to introspection. for name, var_doc in module_doc.variables.items(): if not isinstance(var_doc, ModuleDoc): var_doc.is_imported = UNKNOWN del module_doc.variables['__all__'] # If __path__ is defined, then extract its value (pkgs only) if module_doc.is_package: toktree = _module_var_toktree(module_doc, '__path__') if toktree is not None: try: module_doc.path = parse_string_list(toktree) except ParseError: pass # [xx] del module_doc.variables['__path__'] def _module_var_toktree(module_doc, name): var_doc = module_doc.variables.get(name) if (var_doc is None or var_doc.value in (None, UNKNOWN) or var_doc.value.toktree is UNKNOWN): return None else: return var_doc.value.toktree #//////////////////////////////////////////////////////////// #{ Module Lookup #//////////////////////////////////////////////////////////// def _find(name, package_doc=None): """ Return the API documentaiton for the object whose name is C{name}. C{package_doc}, if specified, is the API documentation for the package containing the named object. """ # If we're inside a package, then find the package's path. if package_doc is None: path = None elif package_doc.path is not UNKNOWN: path = package_doc.path else: path = [os.path.split(package_doc.filename)[0]] # The leftmost identifier in `name` should be a module or # package on the given path; find it and parse it. filename = _get_filename(name[0], path) module_doc = parse_docs(filename, context=package_doc) # If the name just has one identifier, then the module we just # parsed is the object we're looking for; return it. if len(name) == 1: return module_doc # Otherwise, we're looking for something inside the module. # First, check to see if it's in a variable (but ignore # variables that just contain imported submodules). if not _is_submodule_import_var(module_doc, name[1]): try: return _find_in_namespace(name[1:], module_doc) except ImportError: pass # If not, then check to see if it's in a subpackage. if module_doc.is_package: return _find(name[1:], module_doc) # If it's not in a variable or a subpackage, then we can't # find it. raise ImportError('Could not find value') def _is_submodule_import_var(module_doc, var_name): """ Return true if C{var_name} is the name of a variable in C{module_doc} that just contains an C{imported_from} link to a submodule of the same name. (I.e., is a variable created when a package imports one of its own submodules.) """ var_doc = module_doc.variables.get(var_name) full_var_name = DottedName(module_doc.canonical_name, var_name) return (var_doc is not None and var_doc.imported_from == full_var_name) def _find_in_namespace(name, namespace_doc): if name[0] not in namespace_doc.variables: raise ImportError('Could not find value') # Look up the variable in the namespace. var_doc = namespace_doc.variables[name[0]] if var_doc.value is UNKNOWN: raise ImportError('Could not find value') val_doc = var_doc.value # If the variable's value was imported, then follow its # alias link. if var_doc.imported_from not in (None, UNKNOWN): return _find(var_doc.imported_from+name[1:]) # Otherwise, if the name has one identifier, then this is the # value we're looking for; return it. elif len(name) == 1: return val_doc # Otherwise, if this value is a namespace, look inside it. elif isinstance(val_doc, NamespaceDoc): return _find_in_namespace(name[1:], val_doc) # Otherwise, we ran into a dead end. else: raise ImportError('Could not find value') def _get_filename(identifier, path=None): if path is UNKNOWN: path = None try: fp, filename, (s,m,typ) = imp.find_module(identifier, path) if fp is not None: fp.close() except ImportError: raise ImportError, 'No Python source file found.' if typ == imp.PY_SOURCE: return filename elif typ == imp.PY_COMPILED: # See if we can find a corresponding non-compiled version. filename = re.sub('.py\w$', '.py', filename) if not os.path.exists(filename): raise ImportError, 'No Python source file found.' return filename elif typ == imp.PKG_DIRECTORY: filename = os.path.join(filename, '__init__.py') if not os.path.exists(filename): filename = os.path.join(filename, '__init__.pyw') if not os.path.exists(filename): raise ImportError, 'No package file found.' return filename elif typ == imp.C_BUILTIN: raise ImportError, 'No Python source file for builtin modules.' elif typ == imp.C_EXTENSION: raise ImportError, 'No Python source file for c extensions.' else: raise ImportError, 'No Python source file found.' #///////////////////////////////////////////////////////////////// #{ File tokenization loop #///////////////////////////////////////////////////////////////// def process_file(module_doc): """ Read the given C{ModuleDoc}'s file, and add variables corresponding to any objects defined in that file. In particular, read and tokenize C{module_doc.filename}, and process each logical line using L{process_line()}. """ # Keep track of the current line number: lineno = None # Use this list to collect the tokens on a single logical line: line_toks = [] # This list contains one APIDoc for each indentation level. # The first element is the APIDoc for the module, and each # subsequent element is the APIDoc for the object at that # indentation level. The final element of the list is the # C{APIDoc} for the entity that we're currently processing. parent_docs = [module_doc] # The APIDoc for the object that was defined by the previous # line, if any; or None otherwise. This is used to update # parent_docs when we encounter an indent; and to decide what # object (if any) is described by a docstring. prev_line_doc = module_doc # A list of comments that occur before or on the current # logical line, used to build the comment docstring. Each # element is a tuple (comment_text, comment_lineno). comments = [] # A list of decorator lines that occur before the current # logical line. This is used so we can process a function # declaration line and its decorators all at once. decorators = [] # A list of group names, one for each indentation level. This is # used to keep track groups that are defined by comment markers # START_GROUP_MARKER and END_GROUP_MARKER. groups = [None] # When we encounter a comment start group marker, set this to the # name of the group; but wait until we're ready to process the # next line before we actually set groups[-1] to this value. This # is necessary because at the top of a block, the tokenizer gives # us comments before the INDENT token; but if we encounter a group # start marker at the top of a block, then we want it to apply # inside that block, not outside it. start_group = None # Check if the source file declares an encoding. encoding = get_module_encoding(module_doc.filename) # The token-eating loop: try: module_file = codecs.open(module_doc.filename, 'rU', encoding) except LookupError: log.warning("Unknown encoding %r for %s; using the default" "encoding instead (iso-8859-1)" % (encoding, module_doc.filename)) encoding = 'iso-8859-1' module_file = codecs.open(module_doc.filename, 'rU', encoding) tok_iter = tokenize.generate_tokens(module_file.readline) for toktype, toktext, (srow,scol), (erow,ecol), line_str in tok_iter: # BOM encoding marker: ignore. if (toktype == token.ERRORTOKEN and (toktext == u'\ufeff' or toktext.encode(encoding) == '\xef\xbb\xbf')): pass # Error token: abort elif toktype == token.ERRORTOKEN: raise ParseError('Error during parsing: invalid syntax ' '(%s, line %d, char %d: %r)' % (module_doc.filename, srow, scol, toktext)) # Indent token: update the parent_doc stack. elif toktype == token.INDENT: if prev_line_doc is None: parent_docs.append(parent_docs[-1]) else: parent_docs.append(prev_line_doc) groups.append(None) # Dedent token: update the parent_doc stack. elif toktype == token.DEDENT: if line_toks == []: parent_docs.pop() groups.pop() else: # This *should* only happen if the file ends on an # indented line, with no final newline. # (otherwise, this is the wrong thing to do.) pass # Line-internal newline token: if we're still at the start of # the logical line, and we've seen one or more comment lines, # then discard them: blank lines are not allowed between a # comment block and the thing it describes. elif toktype == tokenize.NL: if comments and not line_toks: log.warning('Ignoring docstring comment block followed by ' 'a blank line in %r on line %r' % (module_doc.filename, srow-1)) comments = [] # Comment token: add to comments if appropriate. elif toktype == tokenize.COMMENT: if toktext.startswith(COMMENT_DOCSTRING_MARKER): comment_line = toktext[len(COMMENT_DOCSTRING_MARKER):].rstrip() if comment_line.startswith(" "): comment_line = comment_line[1:] comments.append( [comment_line, srow]) elif toktext.startswith(START_GROUP_MARKER): start_group = toktext[len(START_GROUP_MARKER):].strip() elif toktext.startswith(END_GROUP_MARKER): for i in range(len(groups)-1, -1, -1): if groups[i]: groups[i] = None break else: log.warning("Got group end marker without a corresponding " "start marker in %r on line %r" % (module_doc.filename, srow)) # Normal token: Add it to line_toks. (If it's a non-unicode # string literal, then we need to re-encode using the file's # encoding, to get back to the original 8-bit data; and then # convert that string with 8-bit data to a 7-bit ascii # representation.) elif toktype != token.NEWLINE and toktype != token.ENDMARKER: if lineno is None: lineno = srow if toktype == token.STRING: str_prefixes = re.match('[^\'"]*', toktext).group() if 'u' not in str_prefixes: s = toktext.encode(encoding) toktext = decode_with_backslashreplace(s) line_toks.append( (toktype, toktext) ) # Decorator line: add it to the decorators list. elif line_toks and line_toks[0] == (token.OP, '@'): decorators.append(shallow_parse(line_toks)) line_toks = [] # End of line token, but nothing to do. elif line_toks == []: pass # End of line token: parse the logical line & process it. else: if start_group: groups[-1] = start_group start_group = None if parent_docs[-1] != 'skip_block': try: prev_line_doc = process_line( shallow_parse(line_toks), parent_docs, prev_line_doc, lineno, comments, decorators, encoding) except ParseError, e: raise ParseError('Error during parsing: invalid ' 'syntax (%s, line %d) -- %s' % (module_doc.filename, lineno, e)) except KeyboardInterrupt, e: raise except Exception, e: log.error('Internal error during parsing (%s, line ' '%s):\n%s' % (module_doc.filename, lineno, e)) raise # grouping... if groups[-1] and prev_line_doc not in (None, 'skip_block'): if isinstance(prev_line_doc, VariableDoc): # prev_line_doc's container will only be # UNKNOWN if it's an instance variable that # didn't have a doc-comment, but might still # be followed by a docstring. Since we # tokenize in order, we can't do lookahead to # see if the variable will have a comment; but # it should only be added to the container if # it does. So we defer the grouping of that # to be handled by process_docstring instead. if prev_line_doc.container is not UNKNOWN: add_to_group(prev_line_doc.container, prev_line_doc, groups[-1]) elif isinstance(parent_docs[-1], NamespaceDoc): add_to_group(parent_docs[-1], prev_line_doc, groups[-1]) else: prev_line_doc = None # Reset line contents. line_toks = [] lineno = None comments = [] decorators = [] def add_to_group(container, api_doc, group_name): if container.group_specs is UNKNOWN: container.group_specs = [] if isinstance(api_doc, VariableDoc): var_name = api_doc.name else: if api_doc.canonical_name is UNKNOWN: log.debug('ouch', `api_doc`) var_name = api_doc.canonical_name[-1] for (name, group_vars) in container.group_specs: if name == group_name: group_vars.append(var_name) return else: container.group_specs.append( (group_name, [var_name]) ) def script_guard(line): """Detect the idiomatic trick C{if __name__ == "__main__":}""" return (len(line) == 5 and line[1][1] == '__name__' # this is the most selective and line[0][1] == 'if' and line[2][1] == '==' and line[4][1] == ':' and line[3][1][1:-1] == '__main__') #///////////////////////////////////////////////////////////////// #{ Shallow parser #///////////////////////////////////////////////////////////////// def shallow_parse(line_toks): """ Given a flat list of tokens, return a nested tree structure (called a X{token tree}), whose leaves are identical to the original list, but whose structure reflects the structure implied by the grouping tokens (i.e., parenthases, braces, and brackets). If the parenthases, braces, and brackets do not match, or are not balanced, then raise a ParseError. Assign some structure to a sequence of structure (group parens). """ stack = [[]] parens = [] for tok in line_toks: toktype, toktext = tok if toktext in ('(','[','{'): parens.append(tok) stack.append([tok]) elif toktext in ('}',']',')'): if not parens: raise ParseError('Unbalanced parens') left_paren = parens.pop()[1] if left_paren+toktext not in ('()', '[]', '{}'): raise ParseError('Mismatched parens') lst = stack.pop() lst.append(tok) stack[-1].append(lst) else: stack[-1].append(tok) if len(stack) != 1 or len(parens) != 0: raise ParseError('Unbalanced parens') return stack[0] #///////////////////////////////////////////////////////////////// #{ Line processing #///////////////////////////////////////////////////////////////// # The methods process_*() are used to handle lines. def process_line(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ @return: C{new-doc}, C{decorator}..? """ args = (line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding) if not line: # blank line. return None elif (token.OP, ':') in line[:-1]: return process_one_line_block(*args) elif (token.OP, ';') in line: return process_multi_stmt(*args) elif line[0] == (token.NAME, 'def'): return process_funcdef(*args) elif line[0] == (token.OP, '@'): return process_funcdef(*args) elif line[0] == (token.NAME, 'class'): return process_classdef(*args) elif line[0] == (token.NAME, 'import'): return process_import(*args) elif line[0] == (token.NAME, 'from'): return process_from_import(*args) elif line[0] == (token.NAME, 'del'): return process_del(*args) elif len(line)==1 and line[0][0] == token.STRING: return process_docstring(*args) elif (token.OP, '=') in line: return process_assignment(*args) elif (line[0][0] == token.NAME and line[0][1] in CONTROL_FLOW_KEYWORDS): return process_control_flow_line(*args) else: return None # [xx] do something with control structures like for/if? #///////////////////////////////////////////////////////////////// # Line handler: control flow #///////////////////////////////////////////////////////////////// CONTROL_FLOW_KEYWORDS = [ #: A list of the control flow keywords. If a line begins with #: one of these keywords, then it should be handled by #: C{process_control_flow_line}. 'if', 'elif', 'else', 'while', 'for', 'try', 'except', 'finally'] def process_control_flow_line(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): keyword = line[0][1] # If it's a 'for' block: create the loop variable. if keyword == 'for' and PARSE_FOR_BLOCKS: loopvar_name = parse_dotted_name( split_on(line[1:], (token.NAME, 'in'))[0]) parent = get_lhs_parent(loopvar_name, parent_docs) if parent is not None: var_doc = VariableDoc(name=loopvar_name[-1], is_alias=False, is_imported=False, is_instvar=False, docs_extracted_by='parser') set_variable(parent, var_doc) if ((keyword == 'if' and PARSE_IF_BLOCKS and not script_guard(line)) or (keyword == 'elif' and PARSE_ELSE_BLOCKS) or (keyword == 'else' and PARSE_ELSE_BLOCKS) or (keyword == 'while' and PARSE_WHILE_BLOCKS) or (keyword == 'for' and PARSE_FOR_BLOCKS) or (keyword == 'try' and PARSE_TRY_BLOCKS) or (keyword == 'except' and PARSE_EXCEPT_BLOCKS) or (keyword == 'finally' and PARSE_FINALLY_BLOCKS)): # Return "None" to indicate that we should process the # block using the same context that we were already in. return None else: # Return 'skip_block' to indicate that we should ignore # the contents of this block. return 'skip_block' #///////////////////////////////////////////////////////////////// # Line handler: imports #///////////////////////////////////////////////////////////////// # [xx] I could optionally add ValueDoc's for the imported # variables with proxy_for set to the imported source; but # I don't think I gain much of anything by doing so. def process_import(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): if not isinstance(parent_docs[-1], NamespaceDoc): return names = split_on(line[1:], (token.OP, ',')) for name in names: name_pieces = split_on(name, (token.NAME, 'as')) if len(name_pieces) == 1: src_name = parse_dotted_name(name_pieces[0]) _import_var(src_name, parent_docs) elif len(name_pieces) == 2: if len(name_pieces[1]) != 1: raise ParseError('Expected identifier after "as"') src_name = parse_dotted_name(name_pieces[0]) var_name = parse_name(name_pieces[1][0]) _import_var_as(src_name, var_name, parent_docs) else: raise ParseError('Multiple "as" tokens in import') def process_from_import(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): if not isinstance(parent_docs[-1], NamespaceDoc): return pieces = split_on(line[1:], (token.NAME, 'import')) if len(pieces) != 2 or not pieces[0] or not pieces[1]: raise ParseError("Bad from-import") lhs, rhs = pieces # The RHS might be parenthasized, as specified by PEP 328: # http://www.python.org/peps/pep-0328.html if (len(rhs) == 1 and isinstance(rhs[0], list) and rhs[0][0] == (token.OP, '(') and rhs[0][-1] == (token.OP, ')')): rhs = rhs[0][1:-1] # >>> from __future__ import nested_scopes if lhs == [(token.NAME, '__future__')]: return # >>> from sys import * elif rhs == [(token.OP, '*')]: src_name = parse_dotted_name(lhs) _process_fromstar_import(src_name, parent_docs) # >>> from os.path import join, split else: # Allow relative imports in this case, as per PEP 328 src_name = parse_dotted_name(lhs, parent_name=parent_docs[-1].canonical_name) parts = split_on(rhs, (token.OP, ',')) for part in parts: # from m import x if len(part) == 1: var_name = parse_name(part[0]) _import_var_as(DottedName(src_name, var_name), var_name, parent_docs) # from m import x as y elif len(part) == 3 and part[1] == (token.NAME, 'as'): orig_name = parse_name(part[0]) var_name = parse_name(part[2]) _import_var_as(DottedName(src_name, orig_name), var_name, parent_docs) else: ParseError("Bad from-import") def _process_fromstar_import(src, parent_docs): """ Handle a statement of the form: >>> from import * If L{IMPORT_HANDLING} is C{'parse'}, then first try to parse the module C{M{}}, and copy all of its exported variables to C{parent_docs[-1]}. Otherwise, try to determine the names of the variables exported by C{M{}}, and create a new variable for each export. If L{IMPORT_STAR_HANDLING} is C{'parse'}, then the list of exports if found by parsing C{M{}}; if it is C{'introspect'}, then the list of exports is found by importing and introspecting C{M{}}. """ # This is redundant: already checked by caller. if not isinstance(parent_docs[-1], NamespaceDoc): return # If src is package-local, then convert it to a global name. src = _global_name(src, parent_docs) # Record the import parent_docs[0].imports.append(src) # mark that it's .*?? # [xx] add check for if we already have the source docs in our # cache?? if (IMPORT_HANDLING == 'parse' or IMPORT_STAR_HANDLING == 'parse'): # [xx] is this ok? try: module_doc = _find(src) except ImportError: module_doc = None if isinstance(module_doc, ModuleDoc): for name, imp_var in module_doc.variables.items(): # [xx] this is not exactly correct, but close. It # does the wrong thing if a __var__ is explicitly # listed in __all__. if (imp_var.is_public and not (name.startswith('__') and name.endswith('__'))): var_doc = _add_import_var(DottedName(src, name), name, parent_docs[-1]) if IMPORT_HANDLING == 'parse': var_doc.value = imp_var.value # If we got here, then either IMPORT_HANDLING='link' or we # failed to parse the `src` module. if IMPORT_STAR_HANDLING == 'introspect': try: module = __import__(str(src), {}, {}, [0]) except: return # We couldn't import it. if module is None: return # We couldn't import it. if hasattr(module, '__all__'): names = list(module.__all__) else: names = [n for n in dir(module) if not n.startswith('_')] for name in names: _add_import_var(DottedName(src, name), name, parent_docs[-1]) def _import_var(name, parent_docs): """ Handle a statement of the form: >>> import If L{IMPORT_HANDLING} is C{'parse'}, then first try to find the value by parsing; and create an appropriate variable in parentdoc. Otherwise, add a variable for the imported variable. (More than one variable may be created for cases like C{'import a.b'}, where we need to create a variable C{'a'} in parentdoc containing a proxy module; and a variable C{'b'} in the proxy module. """ # This is redundant: already checked by caller. if not isinstance(parent_docs[-1], NamespaceDoc): return # If name is package-local, then convert it to a global name. src = _global_name(name, parent_docs) src_prefix = src[:len(src)-len(name)] # Record the import parent_docs[0].imports.append(name) # [xx] add check for if we already have the source docs in our # cache?? if IMPORT_HANDLING == 'parse': # Check to make sure that we can actually find the value. try: val_doc = _find(src) except ImportError: val_doc = None if val_doc is not None: # We found it; but it's not the value itself we want to # import, but the module containing it; so import that # module (=top_mod) and create a variable for it. top_mod = src_prefix+name[0] var_doc = _add_import_var(top_mod, name[0], parent_docs[-1]) var_doc.value = _find(DottedName(name[0])) return # If we got here, then either IMPORT_HANDLING='link', or we # did not successfully find the value's docs by parsing; use # a variable with an UNKNOWN value. # Create any necessary intermediate proxy module values. container = parent_docs[-1] for i, identifier in enumerate(name[:-1]): if (identifier not in container.variables or not isinstance(container.variables[identifier], ModuleDoc)): var_doc = _add_import_var(name[:i+1], identifier, container) var_doc.value = ModuleDoc(variables={}, sort_spec=[], proxy_for=src_prefix+name[:i+1], submodules={}, docs_extracted_by='parser') container = container.variables[identifier].value # Add the variable to the container. _add_import_var(src, name[-1], container) def _import_var_as(src, name, parent_docs): """ Handle a statement of the form: >>> import src as name If L{IMPORT_HANDLING} is C{'parse'}, then first try to find the value by parsing; and create an appropriate variable in parentdoc. Otherwise, create a variables with its C{imported_from} attribute pointing to the imported object. """ # This is redundant: already checked by caller. if not isinstance(parent_docs[-1], NamespaceDoc): return # If src is package-local, then convert it to a global name. src = _global_name(src, parent_docs) # Record the import parent_docs[0].imports.append(src) if IMPORT_HANDLING == 'parse': # Parse the value and create a variable for it. try: val_doc = _find(src) except ImportError: val_doc = None if val_doc is not None: var_doc = VariableDoc(name=name, value=val_doc, is_imported=True, is_alias=False, imported_from=src, docs_extracted_by='parser') set_variable(parent_docs[-1], var_doc) return # If we got here, then either IMPORT_HANDLING='link', or we # did not successfully find the value's docs by parsing; use a # variable with a proxy value. _add_import_var(src, name, parent_docs[-1]) def _add_import_var(src, name, container): """ Add a new imported variable named C{name} to C{container}, with C{imported_from=src}. """ var_doc = VariableDoc(name=name, is_imported=True, is_alias=False, imported_from=src, docs_extracted_by='parser') set_variable(container, var_doc) return var_doc def _global_name(name, parent_docs): """ If the given name is package-local (relative to the current context, as determined by C{parent_docs}), then convert it to a global name. """ # Get the containing package from parent_docs. if parent_docs[0].is_package: package = parent_docs[0] else: package = parent_docs[0].package # Check each package (from closest to furthest) to see if it # contains a module named name[0]; if so, then treat `name` as # relative to that package. while package not in (None, UNKNOWN): try: fp = imp.find_module(name[0], package.path)[0] if fp is not None: fp.close() except ImportError: # No submodule found here; try the next package up. package = package.package continue # A submodule was found; return its name. return package.canonical_name + name # We didn't find any package containing `name`; so just return # `name` as-is. return name #///////////////////////////////////////////////////////////////// # Line handler: assignment #///////////////////////////////////////////////////////////////// def process_assignment(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): # Divide the assignment statement into its pieces. pieces = split_on(line, (token.OP, '=')) lhs_pieces = pieces[:-1] rhs = pieces[-1] # Decide whether the variable is an instance variable or not. # If it's an instance var, then discard the value. is_instvar = lhs_is_instvar(lhs_pieces, parent_docs) # if it's not an instance var, and we're not in a namespace, # then it's just a local var -- so ignore it. if not (is_instvar or isinstance(parent_docs[-1], NamespaceDoc)): return None # Evaluate the right hand side. if not is_instvar: rhs_val, is_alias = rhs_to_valuedoc(rhs, parent_docs) else: rhs_val, is_alias = UNKNOWN, False # Assign the right hand side value to each left hand side. # (Do the rightmost assignment first) lhs_pieces.reverse() for lhs in lhs_pieces: # Try treating the LHS as a simple dotted name. try: lhs_name = parse_dotted_name(lhs) except: lhs_name = None if lhs_name is not None: lhs_parent = get_lhs_parent(lhs_name, parent_docs) if lhs_parent is None: continue # Skip a special class variable. if lhs_name[-1] == '__slots__': continue # Create the VariableDoc. var_doc = VariableDoc(name=lhs_name[-1], value=rhs_val, is_imported=False, is_alias=is_alias, is_instvar=is_instvar, docs_extracted_by='parser') # Extract a docstring from the comments, when present, # but only if there's a single LHS. if len(lhs_pieces) == 1: add_docstring_from_comments(var_doc, comments) # Assign the variable to the containing namespace, # *unless* the variable is an instance variable # without a comment docstring. In that case, we'll # only want to add it if we later discover that it's # followed by a variable docstring. If it is, then # process_docstring will take care of adding it to the # containing clas. (This is a little hackish, but # unfortunately is necessary because we won't know if # this assignment line is followed by a docstring # until later.) if (not is_instvar) or comments: set_variable(lhs_parent, var_doc, True) # If it's the only var, then return the VarDoc for use # as the new `prev_line_doc`. if (len(lhs_pieces) == 1 and (len(lhs_name) == 1 or is_instvar)): return var_doc # Otherwise, the LHS must be a complex expression; use # dotted_names_in() to decide what variables it contains, # and create VariableDoc's for all of them (with UNKNOWN # value). else: for lhs_name in dotted_names_in(lhs_pieces): lhs_parent = get_lhs_parent(lhs_name, parent_docs) if lhs_parent is None: continue var_doc = VariableDoc(name=lhs_name[-1], is_imported=False, is_alias=is_alias, is_instvar=is_instvar, docs_extracted_by='parser') set_variable(lhs_parent, var_doc, True) # If we have multiple left-hand-sides, then all but the # rightmost one are considered aliases. is_alias = True def lhs_is_instvar(lhs_pieces, parent_docs): if not isinstance(parent_docs[-1], RoutineDoc): return False # make sure that lhs_pieces is ., where is # the name of the first arg to the containing routinedoc, and # is a simple name. posargs = parent_docs[-1].posargs if posargs is UNKNOWN: return False if not (len(lhs_pieces)==1 and len(posargs) > 0 and len(lhs_pieces[0]) == 3 and lhs_pieces[0][0] == (token.NAME, posargs[0]) and lhs_pieces[0][1] == (token.OP, '.') and lhs_pieces[0][2][0] == token.NAME): return False # Make sure we're in an instance method, and not a # module-level function. for i in range(len(parent_docs)-1, -1, -1): if isinstance(parent_docs[i], ClassDoc): return True elif parent_docs[i] != parent_docs[-1]: return False return False def rhs_to_valuedoc(rhs, parent_docs): # Dotted variable: try: rhs_name = parse_dotted_name(rhs) rhs_val = lookup_value(rhs_name, parent_docs) if rhs_val is not None and rhs_val is not UNKNOWN: return rhs_val, True except ParseError: pass # Decorators: if (len(rhs)==2 and rhs[0][0] == token.NAME and isinstance(rhs[1], list)): arg_val, _ = rhs_to_valuedoc(rhs[1][1:-1], parent_docs) if isinstance(arg_val, RoutineDoc): doc = apply_decorator(DottedName(rhs[0][1]), arg_val) doc.canonical_name = UNKNOWN doc.parse_repr = pp_toktree(rhs) return doc, False # Nothing else to do: make a val with the source as its repr. return GenericValueDoc(parse_repr=pp_toktree(rhs), toktree=rhs, defining_module=parent_docs[0], docs_extracted_by='parser'), False def get_lhs_parent(lhs_name, parent_docs): assert isinstance(lhs_name, DottedName) # For instance vars inside an __init__ method: if isinstance(parent_docs[-1], RoutineDoc): for i in range(len(parent_docs)-1, -1, -1): if isinstance(parent_docs[i], ClassDoc): return parent_docs[i] else: raise ValueError("%r is not a namespace or method" % parent_docs[-1]) # For local variables: if len(lhs_name) == 1: return parent_docs[-1] # For non-local variables: return lookup_value(lhs_name.container(), parent_docs) #///////////////////////////////////////////////////////////////// # Line handler: single-line blocks #///////////////////////////////////////////////////////////////// def process_one_line_block(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for single-line blocks, such as: >>> def f(x): return x*2 This handler calls L{process_line} twice: once for the tokens up to and including the colon, and once for the remaining tokens. The comment docstring is applied to the first line only. @return: C{None} """ i = line.index((token.OP, ':')) doc1 = process_line(line[:i+1], parent_docs, prev_line_doc, lineno, comments, decorators, encoding) doc2 = process_line(line[i+1:], parent_docs+[doc1], doc1, lineno, None, [], encoding) return doc1 #///////////////////////////////////////////////////////////////// # Line handler: semicolon-separated statements #///////////////////////////////////////////////////////////////// def process_multi_stmt(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for semicolon-separated statements, such as: >>> x=1; y=2; z=3 This handler calls L{process_line} once for each statement. The comment docstring is not passed on to any of the sub-statements. @return: C{None} """ for statement in split_on(line, (token.OP, ';')): if not statement: continue doc = process_line(statement, parent_docs, prev_line_doc, lineno, None, decorators, encoding) prev_line_doc = doc decorators = [] return None #///////////////////////////////////////////////////////////////// # Line handler: delete statements #///////////////////////////////////////////////////////////////// def process_del(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for delete statements, such as: >>> del x, y.z This handler calls L{del_variable} for each dotted variable in the variable list. The variable list may be nested. Complex expressions in the variable list (such as C{x[3]}) are ignored. @return: C{None} """ # If we're not in a namespace, then ignore it. parent_doc = parent_docs[-1] if not isinstance(parent_doc, NamespaceDoc): return var_list = split_on(line[1:], (token.OP, ',')) for var_name in dotted_names_in(var_list): del_variable(parent_docs[-1], var_name) return None #///////////////////////////////////////////////////////////////// # Line handler: docstrings #///////////////////////////////////////////////////////////////// def process_docstring(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for bare string literals. If C{prev_line_doc} is not C{None}, then the string literal is added to that C{APIDoc} as a docstring. If it already has a docstring (from comment docstrings), then the new docstring will be appended to the old one. """ if prev_line_doc is None: return docstring = parse_string(line) # If the docstring is a str, then convert it to unicode. # According to a strict reading of PEP 263, this might not be the # right thing to do; but it will almost always be what the # module's author intended. if isinstance(docstring, str): try: docstring = docstring.decode(encoding) except UnicodeDecodeError: # If decoding failed, then fall back on using # decode_with_backslashreplace, which will map e.g. # "\xe9" -> u"\\xe9". docstring = decode_with_backslashreplace(docstring) log.warning("While parsing %s: docstring is not a unicode " "string, but it contains non-ascii data." % prev_line_doc.canonical_name) # If the modified APIDoc is an instance variable, and it has # not yet been added to its class's C{variables} list, # then add it now. This is done here, rather than in the # process_assignment() call that created the variable, because # we only want to add instance variables if they have an # associated docstring. (For more info, see the comment above # the set_variable() call in process_assignment().) added_instvar = False if (isinstance(prev_line_doc, VariableDoc) and prev_line_doc.is_instvar and prev_line_doc.docstring in (None, UNKNOWN)): for i in range(len(parent_docs)-1, -1, -1): if isinstance(parent_docs[i], ClassDoc): set_variable(parent_docs[i], prev_line_doc, True) added_instvar = True break if prev_line_doc.docstring not in (None, UNKNOWN): log.warning("%s has both a comment-docstring and a normal " "(string) docstring; ignoring the comment-" "docstring." % prev_line_doc.canonical_name) prev_line_doc.docstring = docstring prev_line_doc.docstring_lineno = lineno # If the modified APIDoc is an instance variable, and we added it # to the class's variables list here, then it still needs to be # grouped too; so return it for use as the new "prev_line_doc." if added_instvar: return prev_line_doc #///////////////////////////////////////////////////////////////// # Line handler: function declarations #///////////////////////////////////////////////////////////////// def process_funcdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for function declaration lines, such as: >>> def f(a, b=22, (c,d)): This handler creates and initializes a new C{VariableDoc} containing a C{RoutineDoc}, adds the C{VariableDoc} to the containing namespace, and returns the C{RoutineDoc}. """ # Check syntax. if len(line) != 4 or line[3] != (token.OP, ':'): raise ParseError("Bad function definition line") # If we're not in a namespace, then ignore it. parent_doc = parent_docs[-1] if not isinstance(parent_doc, NamespaceDoc): return # Get the function's name func_name = parse_name(line[1]) canonical_name = DottedName(parent_doc.canonical_name, func_name) # Create the function's RoutineDoc. func_doc = RoutineDoc(canonical_name=canonical_name, defining_module=parent_docs[0], lineno=lineno, docs_extracted_by='parser') # Process the signature. init_arglist(func_doc, line[2]) # If the preceeding comment includes a docstring, then add it. add_docstring_from_comments(func_doc, comments) # Apply any decorators. func_doc.decorators = [pp_toktree(deco[1:]) for deco in decorators] decorators.reverse() for decorator in decorators: try: deco_name = parse_dotted_name(decorator[1:]) except ParseError: deco_name = None if func_doc.canonical_name is not UNKNOWN: deco_repr = '%s(%s)' % (pp_toktree(decorator[1:]), func_doc.canonical_name) elif func_doc.parse_repr not in (None, UNKNOWN): # [xx] this case should be improved.. when will func_doc # have a known parse_repr?? deco_repr = '%s(%s)' % (pp_toktree(decorator[1:]), func_doc.parse_repr) else: deco_repr = UNKNOWN func_doc = apply_decorator(deco_name, func_doc) func_doc.parse_repr = deco_repr # [XX] Is there a reson the following should be done? It # causes the grouping code to break. Presumably the canonical # name should remain valid if we're just applying a standard # decorator. #func_doc.canonical_name = UNKNOWN # Add a variable to the containing namespace. var_doc = VariableDoc(name=func_name, value=func_doc, is_imported=False, is_alias=False, docs_extracted_by='parser') set_variable(parent_doc, var_doc) # Return the new ValueDoc. return func_doc def apply_decorator(decorator_name, func_doc): # [xx] what if func_doc is not a RoutineDoc? if decorator_name == DottedName('staticmethod'): return StaticMethodDoc(**func_doc.__dict__) elif decorator_name == DottedName('classmethod'): return ClassMethodDoc(**func_doc.__dict__) elif DEFAULT_DECORATOR_BEHAVIOR == 'transparent': return func_doc.__class__(**func_doc.__dict__) # make a copy. elif DEFAULT_DECORATOR_BEHAVIOR == 'opaque': return GenericValueDoc(docs_extracted_by='parser') else: raise ValueError, 'Bad value for DEFAULT_DECORATOR_BEHAVIOR' def init_arglist(func_doc, arglist): if not isinstance(arglist, list) or arglist[0] != (token.OP, '('): raise ParseError("Bad argument list") # Initialize to defaults. func_doc.posargs = [] func_doc.posarg_defaults = [] func_doc.vararg = None func_doc.kwarg = None # Divide the arglist into individual args. args = split_on(arglist[1:-1], (token.OP, ',')) # Keyword argument. if args and args[-1][0] == (token.OP, '**'): if len(args[-1]) != 2 or args[-1][1][0] != token.NAME: raise ParseError("Expected name after ** in argument list") func_doc.kwarg = args[-1][1][1] args.pop() # Vararg argument. if args and args[-1][0] == (token.OP, '*'): if len(args[-1]) != 2 or args[-1][1][0] != token.NAME: raise ParseError("Expected name after * in argument list") func_doc.vararg = args[-1][1][1] args.pop() # Positional arguments. for arg in args: func_doc.posargs.append(parse_funcdef_arg(arg[0])) if len(arg) == 1: func_doc.posarg_defaults.append(None) elif arg[1] != (token.OP, '=') or len(arg) == 2: raise ParseError("Bad argument list") else: default_repr = pp_toktree(arg[2:], 'tight') default_val = GenericValueDoc(parse_repr=default_repr, docs_extracted_by='parser') func_doc.posarg_defaults.append(default_val) #///////////////////////////////////////////////////////////////// # Line handler: class declarations #///////////////////////////////////////////////////////////////// def process_classdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding): """ The line handler for class declaration lines, such as: >>> class Foo(Bar, Baz): This handler creates and initializes a new C{VariableDoc} containing a C{ClassDoc}, adds the C{VariableDoc} to the containing namespace, and returns the C{ClassDoc}. """ # Check syntax if len(line)<3 or len(line)>4 or line[-1] != (token.OP, ':'): raise ParseError("Bad class definition line") # If we're not in a namespace, then ignore it. parent_doc = parent_docs[-1] if not isinstance(parent_doc, NamespaceDoc): return # Get the class's name class_name = parse_name(line[1]) canonical_name = DottedName(parent_doc.canonical_name, class_name) # Create the class's ClassDoc & VariableDoc. class_doc = ClassDoc(variables={}, sort_spec=[], bases=[], subclasses=[], canonical_name=canonical_name, defining_module=parent_docs[0], docs_extracted_by='parser') var_doc = VariableDoc(name=class_name, value=class_doc, is_imported=False, is_alias=False, docs_extracted_by='parser') # Add the bases. if len(line) == 4: if (not isinstance(line[2], list) or line[2][0] != (token.OP, '(')): raise ParseError("Expected base list") try: for base_name in parse_classdef_bases(line[2]): class_doc.bases.append(find_base(base_name, parent_docs)) except ParseError, e: log.warning("Unable to extract the base list for %s: %s" % (canonical_name, e)) class_doc.bases = UNKNOWN else: class_doc.bases = [] # Register ourselves as a subclass to our bases. if class_doc.bases is not UNKNOWN: for basedoc in class_doc.bases: if isinstance(basedoc, ClassDoc): # This test avoids that a subclass gets listed twice when # both introspection and parsing. # [XXX] This check only works because currently parsing is # always performed just after introspection of the same # class. A more complete fix shuld be independent from # calling order; probably the subclasses list should be # replaced by a ClassDoc set or a {name: ClassDoc} mapping. if (basedoc.subclasses and basedoc.subclasses[-1].canonical_name != class_doc.canonical_name): basedoc.subclasses.append(class_doc) # If the preceeding comment includes a docstring, then add it. add_docstring_from_comments(class_doc, comments) # Add the VariableDoc to our container. set_variable(parent_doc, var_doc) return class_doc def _proxy_base(**attribs): return ClassDoc(variables={}, sort_spec=[], bases=[], subclasses=[], docs_extracted_by='parser', **attribs) def find_base(name, parent_docs): assert isinstance(name, DottedName) # Find the variable containing the base. base_var = lookup_variable(name, parent_docs) if base_var is None: # If we didn't find it, then it must have been imported. # First, check if it looks like it's contained in any # known imported variable: if len(name) > 1: src = lookup_name(name[0], parent_docs) if (src is not None and src.imported_from not in (None, UNKNOWN)): base_src = DottedName(src.imported_from, name[1:]) base_var = VariableDoc(name=name[-1], is_imported=True, is_alias=False, imported_from=base_src, docs_extracted_by='parser') # Otherwise, it must have come from an "import *" statement # (or from magic, such as direct manipulation of the module's # dictionary), so we don't know where it came from. So # there's nothing left but to use an empty proxy. if base_var is None: return _proxy_base(parse_repr=str(name)) #raise ParseError("Could not find %s" % name) # If the variable has a value, return that value. if base_var.value is not UNKNOWN: return base_var.value # Otherwise, if BASE_HANDLING is 'parse', try parsing the docs for # the base class; if that fails, or if BASE_HANDLING is 'link', # just make a proxy object. if base_var.imported_from not in (None, UNKNOWN): if BASE_HANDLING == 'parse': old_sys_path = sys.path try: dirname = os.path.split(parent_docs[0].filename)[0] sys.path = [dirname] + sys.path try: return parse_docs(name=str(base_var.imported_from)) except ParseError: log.info('Unable to parse base', base_var.imported_from) except ImportError: log.info('Unable to find base', base_var.imported_from) finally: sys.path = old_sys_path # Either BASE_HANDLING='link' or parsing the base class failed; # return a proxy value for the base class. return _proxy_base(proxy_for=base_var.imported_from) else: return _proxy_base(parse_repr=str(name)) #///////////////////////////////////////////////////////////////// #{ Parsing #///////////////////////////////////////////////////////////////// def dotted_names_in(elt_list): """ Return a list of all simple dotted names in the given expression. """ names = [] while elt_list: elt = elt_list.pop() if len(elt) == 1 and isinstance(elt[0], list): # Nested list: process the contents elt_list.extend(split_on(elt[0][1:-1], (token.OP, ','))) else: try: names.append(parse_dotted_name(elt)) except ParseError: pass # complex expression -- ignore return names def parse_name(elt, strip_parens=False): """ If the given token tree element is a name token, then return that name as a string. Otherwise, raise ParseError. @param strip_parens: If true, then if elt is a single name enclosed in parenthases, then return that name. """ if strip_parens and isinstance(elt, list): while (isinstance(elt, list) and len(elt) == 3 and elt[0] == (token.OP, '(') and elt[-1] == (token.OP, ')')): elt = elt[1] if isinstance(elt, list) or elt[0] != token.NAME: raise ParseError("Bad name") return elt[1] def parse_dotted_name(elt_list, strip_parens=True, parent_name=None): """ @param parent_name: canonical name of referring module, to resolve relative imports. @type parent_name: L{DottedName} @bug: does not handle 'x.(y).z' """ if len(elt_list) == 0: raise ParseError("Bad dotted name") # Handle ((x.y).z). (If the contents of the parens include # anything other than dotted names, such as (x,y), then we'll # catch it below and raise a ParseError. while (isinstance(elt_list[0], list) and len(elt_list[0]) >= 3 and elt_list[0][0] == (token.OP, '(') and elt_list[0][-1] == (token.OP, ')')): elt_list[:1] = elt_list[0][1:-1] # Convert a relative import into an absolute name. prefix_name = None if parent_name is not None and elt_list[0][-1] == '.': items = 1 while len(elt_list) > items and elt_list[items][-1] == '.': items += 1 elt_list = elt_list[items:] prefix_name = parent_name[:-items] # >>> from . import foo if not elt_list: if prefix_name == []: raise ParseError("Attempted relative import in non-package, " "or beyond toplevel package") return prefix_name if len(elt_list) % 2 != 1: raise ParseError("Bad dotted name") name = DottedName(parse_name(elt_list[0], True)) if prefix_name is not None: name = prefix_name + name for i in range(2, len(elt_list), 2): dot, identifier = elt_list[i-1], elt_list[i] if dot != (token.OP, '.'): raise ParseError("Bad dotted name") name = DottedName(name, parse_name(identifier, True)) return name def split_on(elt_list, split_tok): # [xx] add code to guarantee each elt is non-empty. result = [[]] for elt in elt_list: if elt == split_tok: if result[-1] == []: raise ParseError("Empty element from split") result.append([]) else: result[-1].append(elt) if result[-1] == []: result.pop() return result def parse_funcdef_arg(elt): """ If the given tree token element contains a valid function definition argument (i.e., an identifier token or nested list of identifiers), then return a corresponding string identifier or nested list of string identifiers. Otherwise, raise a ParseError. """ if isinstance(elt, list): if elt[0] == (token.OP, '('): if len(elt) == 3: return parse_funcdef_arg(elt[1]) else: return [parse_funcdef_arg(e) for e in elt[1:-1] if e != (token.OP, ',')] else: raise ParseError("Bad argument -- expected name or tuple") elif elt[0] == token.NAME: return elt[1] else: raise ParseError("Bad argument -- expected name or tuple") def parse_classdef_bases(elt): """ If the given tree token element contains a valid base list (that contains only dotted names), then return a corresponding list of L{DottedName}s. Otherwise, raise a ParseError. @bug: Does not handle either of:: - class A( (base.in.parens) ): pass - class B( (lambda:calculated.base)() ): pass """ if (not isinstance(elt, list) or elt[0] != (token.OP, '(')): raise ParseError("Bad base list") return [parse_dotted_name(n) for n in split_on(elt[1:-1], (token.OP, ','))] # Used by: base list; 'del'; ... def parse_dotted_name_list(elt_list): """ If the given list of tree token elements contains a comma-separated list of dotted names, then return a corresponding list of L{DottedName} objects. Otherwise, raise ParseError. """ names = [] state = 0 for elt in elt_list: # State 0 -- Expecting a name, or end of arglist if state == 0: # Make sure it's a name if isinstance(elt, tuple) and elt[0] == token.NAME: names.append(DottedName(elt[1])) state = 1 else: raise ParseError("Expected a name") # State 1 -- Expecting comma, period, or end of arglist elif state == 1: if elt == (token.OP, '.'): state = 2 elif elt == (token.OP, ','): state = 0 else: raise ParseError("Expected '.' or ',' or end of list") # State 2 -- Continuation of dotted name. elif state == 2: if isinstance(elt, tuple) and elt[0] == token.NAME: names[-1] = DottedName(names[-1], elt[1]) state = 1 else: raise ParseError("Expected a name") if state == 2: raise ParseError("Expected a name") return names def parse_string(elt_list): if len(elt_list) == 1 and elt_list[0][0] == token.STRING: # [xx] use something safer here? But it needs to deal with # any string type (eg r"foo\bar" etc). return eval(elt_list[0][1]) else: raise ParseError("Expected a string") # ['1', 'b', 'c'] def parse_string_list(elt_list): if (len(elt_list) == 1 and isinstance(elt_list, list) and elt_list[0][0][1] in ('(', '[')): elt_list = elt_list[0][1:-1] string_list = [] for string_elt in split_on(elt_list, (token.OP, ',')): string_list.append(parse_string(string_elt)) return string_list #///////////////////////////////////////////////////////////////// #{ Variable Manipulation #///////////////////////////////////////////////////////////////// def set_variable(namespace, var_doc, preserve_docstring=False): """ Add var_doc to namespace. If namespace already contains a variable with the same name, then discard the old variable. If C{preserve_docstring} is true, then keep the old variable's docstring when overwriting a variable. """ # Choose which dictionary we'll be storing the variable in. if not isinstance(namespace, NamespaceDoc): return # This happens when the class definition has not been parsed, e.g. in # sf bug #1693253 on ``Exception.x = y`` if namespace.sort_spec is UNKNOWN: namespace.sort_spec = namespace.variables.keys() # If we already have a variable with this name, then remove the # old VariableDoc from the sort_spec list; and if we gave its # value a canonical name, then delete it. if var_doc.name in namespace.variables: namespace.sort_spec.remove(var_doc.name) old_var_doc = namespace.variables[var_doc.name] if (old_var_doc.is_alias == False and old_var_doc.value is not UNKNOWN): old_var_doc.value.canonical_name = UNKNOWN if (preserve_docstring and var_doc.docstring in (None, UNKNOWN) and old_var_doc.docstring not in (None, UNKNOWN)): var_doc.docstring = old_var_doc.docstring var_doc.docstring_lineno = old_var_doc.docstring_lineno # Add the variable to the namespace. namespace.variables[var_doc.name] = var_doc namespace.sort_spec.append(var_doc.name) assert var_doc.container is UNKNOWN var_doc.container = namespace def del_variable(namespace, name): if not isinstance(namespace, NamespaceDoc): return if name[0] in namespace.variables: if len(name) == 1: var_doc = namespace.variables[name[0]] namespace.sort_spec.remove(name[0]) del namespace.variables[name[0]] if not var_doc.is_alias and var_doc.value is not UNKNOWN: var_doc.value.canonical_name = UNKNOWN else: del_variable(namespace.variables[name[0]].value, name[1:]) #///////////////////////////////////////////////////////////////// #{ Name Lookup #///////////////////////////////////////////////////////////////// def lookup_name(identifier, parent_docs): """ Find and return the documentation for the variable named by the given identifier. @rtype: L{VariableDoc} or C{None} """ # We need to check 3 namespaces: locals, globals, and builtins. # Note that this is true even if we're in a version of python with # nested scopes, because nested scope lookup does not apply to # nested class definitions, and we're not worried about variables # in nested functions. if not isinstance(identifier, basestring): raise TypeError('identifier must be a string') # Locals if isinstance(parent_docs[-1], NamespaceDoc): if identifier in parent_docs[-1].variables: return parent_docs[-1].variables[identifier] # Globals (aka the containing module) if isinstance(parent_docs[0], NamespaceDoc): if identifier in parent_docs[0].variables: return parent_docs[0].variables[identifier] # Builtins builtins = epydoc.docintrospecter.introspect_docs(__builtin__) if isinstance(builtins, NamespaceDoc): if identifier in builtins.variables: return builtins.variables[identifier] # We didn't find it; return None. return None def lookup_variable(dotted_name, parent_docs): assert isinstance(dotted_name, DottedName) # If it's a simple identifier, use lookup_name. if len(dotted_name) == 1: return lookup_name(dotted_name[0], parent_docs) # If it's a dotted name with multiple pieces, look up the # namespace containing the var (=parent) first; and then # look for the var in that namespace. else: parent = lookup_value(dotted_name[:-1], parent_docs) if (isinstance(parent, NamespaceDoc) and dotted_name[-1] in parent.variables): return parent.variables[dotted_name[-1]] else: return None # var not found. def lookup_value(dotted_name, parent_docs): """ Find and return the documentation for the value contained in the variable with the given name in the current namespace. """ assert isinstance(dotted_name, DottedName) var_doc = lookup_name(dotted_name[0], parent_docs) for i in range(1, len(dotted_name)): if var_doc is None: return None if isinstance(var_doc.value, NamespaceDoc): var_dict = var_doc.value.variables elif (var_doc.value is UNKNOWN and var_doc.imported_from not in (None, UNKNOWN)): src_name = var_doc.imported_from + dotted_name[i:] # [xx] do I want to create a proxy here?? return GenericValueDoc(proxy_for=src_name, parse_repr=str(dotted_name), docs_extracted_by='parser') else: return None var_doc = var_dict.get(dotted_name[i]) if var_doc is None: return None return var_doc.value #///////////////////////////////////////////////////////////////// #{ Docstring Comments #///////////////////////////////////////////////////////////////// def add_docstring_from_comments(api_doc, comments): if api_doc is None or not comments: return api_doc.docstring = '\n'.join([line for (line, lineno) in comments]) api_doc.docstring_lineno = comments[0][1] #///////////////////////////////////////////////////////////////// #{ Tree tokens #///////////////////////////////////////////////////////////////// def _join_toktree(s1, s2): # Join them. s1 = left side; s2 = right side. if (s2=='' or s1=='' or s1 in ('-','`') or s2 in ('}',']',')','`',':') or s2[0] in ('.',',') or s1[-1] in ('(','[','{','.','\n',' ') or (s2[0] == '(' and s1[-1] not in (',','='))): return '%s%s' % (s1,s2) elif (spacing=='tight' and s1[-1] in '+-*/=,' or s2[0] in '+-*/=,'): return '%s%s' % (s1, s2) else: return '%s %s' % (s1, s2) def _pp_toktree_add_piece(spacing, pieces, piece): s1 = pieces[-1] s2 = piece if (s2=='' or s1=='' or s1 in ('-','`') or s2 in ('}',']',')','`',':') or s2[0] in ('.',',') or s1[-1] in ('(','[','{','.','\n',' ') or (s2[0] == '(' and s1[-1] not in (',','='))): pass elif (spacing=='tight' and s1[-1] in '+-*/=,' or s2[0] in '+-*/=,'): pass else: pieces.append(' ') pieces.append(piece) def pp_toktree(elts, spacing='normal', indent=0): pieces = [''] _pp_toktree(elts, spacing, indent, pieces) return ''.join(pieces) def _pp_toktree(elts, spacing, indent, pieces): add_piece = _pp_toktree_add_piece for elt in elts: # Put a blank line before class & def statements. if elt == (token.NAME, 'class') or elt == (token.NAME, 'def'): add_piece(spacing, pieces, '\n%s' % (' '*indent)) if isinstance(elt, tuple): if elt[0] == token.NEWLINE: add_piece(spacing, pieces, ' '+elt[1]) add_piece(spacing, pieces, '\n%s' % (' '*indent)) elif elt[0] == token.INDENT: add_piece(spacing, pieces, ' ') indent += 1 elif elt[0] == token.DEDENT: assert pieces[-1] == ' ' pieces.pop() indent -= 1 elif elt[0] == tokenize.COMMENT: add_piece(spacing, pieces, elt[1].rstrip() + '\n') add_piece(' '*indent) else: add_piece(spacing, pieces, elt[1]) else: _pp_toktree(elt, spacing, indent, pieces) #///////////////////////////////////////////////////////////////// #{ Helper Functions #///////////////////////////////////////////////////////////////// def get_module_encoding(filename): """ @see: U{PEP 263} """ module_file = open(filename, 'rU') try: lines = [module_file.readline() for i in range(2)] if lines[0].startswith('\xef\xbb\xbf'): return 'utf-8' else: for line in lines: m = re.search("coding[:=]\s*([-\w.]+)", line) if m: return m.group(1) # Fall back on Python's default encoding. return 'iso-8859-1' # aka 'latin-1' finally: module_file.close() def _get_module_name(filename, package_doc): """ Return (dotted_name, is_package) """ name = re.sub(r'.py\w?$', '', os.path.split(filename)[1]) if name == '__init__': is_package = True name = os.path.split(os.path.split(filename)[0])[1] else: is_package = False # [XX] if the module contains a script, then `name` may not # necessarily be a valid identifier -- which will cause # DottedName to raise an exception. Is that what I want? if package_doc is None: dotted_name = DottedName(name) else: dotted_name = DottedName(package_doc.canonical_name, name) # Check if the module looks like it's shadowed by a variable. # If so, then add a "'" to the end of its canonical name, to # distinguish it from the variable. if package_doc is not None and name in package_doc.variables: vardoc = package_doc.variables[name] if (vardoc.value not in (None, UNKNOWN) and vardoc.imported_from != dotted_name): log.warning("Module %s might be shadowed by a variable with " "the same name." % dotted_name) dotted_name = DottedName(str(dotted_name)+"'") return dotted_name, is_package def flatten(lst, out=None): """ @return: a flat list containing the leaves of the given nested list. @param lst: The nested list that should be flattened. """ if out is None: out = [] for elt in lst: if isinstance(elt, (list, tuple)): flatten(elt, out) else: out.append(elt) return out epydoc-3.0.1+dfsg/epydoc/markup/0002755000175000017500000000000010750103105016751 5ustar pronovicpronovicepydoc-3.0.1+dfsg/epydoc/markup/doctest.py0000644000175000017500000003141510654406437021013 0ustar pronovicpronovic# # doctest.py: Syntax Highlighting for doctest blocks # Edward Loper # # Created [06/28/03 02:52 AM] # $Id: restructuredtext.py 1210 2006-04-10 13:25:50Z edloper $ # """ Syntax highlighting for doctest blocks. This module defines two functions, L{doctest_to_html()} and L{doctest_to_latex()}, which can be used to perform syntax highlighting on doctest blocks. It also defines the more general C{colorize_doctest()}, which could be used to do syntac highlighting on doctest blocks with other output formats. (Both C{doctest_to_html()} and C{doctest_to_latex()} are defined using C{colorize_doctest()}.) """ __docformat__ = 'epytext en' import re from epydoc.util import plaintext_to_html, plaintext_to_latex __all__ = ['doctest_to_html', 'doctest_to_latex', 'DoctestColorizer', 'XMLDoctestColorizer', 'HTMLDoctestColorizer', 'LaTeXDoctestColorizer'] def doctest_to_html(s): """ Perform syntax highlighting on the given doctest string, and return the resulting HTML code. This code consists of a C{
      }
          block with class=py-doctest.  Syntax highlighting is performed
          using the following css classes:
          
            - C{py-prompt} -- the Python PS1 prompt (>>>)
            - C{py-more} -- the Python PS2 prompt (...)
            - C{py-keyword} -- a Python keyword (for, if, etc.)
            - C{py-builtin} -- a Python builtin name (abs, dir, etc.)
            - C{py-string} -- a string literal
            - C{py-comment} -- a comment
            - C{py-except} -- an exception traceback (up to the next >>>)
            - C{py-output} -- the output from a doctest block.
            - C{py-defname} -- the name of a function or class defined by
              a C{def} or C{class} statement.
          """
          return HTMLDoctestColorizer().colorize_doctest(s)
      
      def doctest_to_latex(s):
          """
          Perform syntax highlighting on the given doctest string, and
          return the resulting LaTeX code.  This code consists of an
          C{alltt} environment.  Syntax highlighting is performed using 
          the following new latex commands, which must be defined externally:
            - C{\pysrcprompt} -- the Python PS1 prompt (>>>)
            - C{\pysrcmore} -- the Python PS2 prompt (...)
            - C{\pysrckeyword} -- a Python keyword (for, if, etc.)
            - C{\pysrcbuiltin} -- a Python builtin name (abs, dir, etc.)
            - C{\pysrcstring} -- a string literal
            - C{\pysrccomment} -- a comment
            - C{\pysrcexcept} -- an exception traceback (up to the next >>>)
            - C{\pysrcoutput} -- the output from a doctest block.
            - C{\pysrcdefname} -- the name of a function or class defined by
              a C{def} or C{class} statement.
          """
          return LaTeXDoctestColorizer().colorize_doctest(s)
      
      class DoctestColorizer:
          """
          An abstract base class for performing syntax highlighting on
          doctest blocks and other bits of Python code.  Subclasses should
          provide definitions for:
      
            - The L{markup()} method, which takes a substring and a tag, and
              returns a colorized version of the substring.
            - The L{PREFIX} and L{SUFFIX} variables, which will be added
              to the beginning and end of the strings returned by
              L{colorize_codeblock} and L{colorize_doctest}.  
          """
      
          #: A string that is added to the beginning of the strings
          #: returned by L{colorize_codeblock} and L{colorize_doctest}.
          #: Typically, this string begins a preformatted area.
          PREFIX = None
      
          #: A string that is added to the end of the strings
          #: returned by L{colorize_codeblock} and L{colorize_doctest}.
          #: Typically, this string ends a preformatted area.
          SUFFIX = None
      
          #: A list of the names of all Python keywords.  ('as' is included
          #: even though it is technically not a keyword.)
          _KEYWORDS = ("and       del       for       is        raise"
                       "assert    elif      from      lambda    return"
                       "break     else      global    not       try"
                       "class     except    if        or        while"
                       "continue  exec      import    pass      yield"
                       "def       finally   in        print     as").split()
      
          #: A list of all Python builtins.
          _BUILTINS = [_BI for _BI in dir(__builtins__)
                       if not _BI.startswith('__')]
      
          #: A regexp group that matches keywords.
          _KEYWORD_GRP = '|'.join([r'\b%s\b' % _KW for _KW in _KEYWORDS])
      
          #: A regexp group that matches Python builtins.
          _BUILTIN_GRP = (r'(?>>" prompts.
          _PROMPT1_GRP = r'^[ \t]*>>>(?:[ \t]|$)'
          
          #: A regexp group that matches Python "..." prompts.
          _PROMPT2_GRP = r'^[ \t]*\.\.\.(?:[ \t]|$)'
      
          #: A regexp group that matches function and class definitions.
          _DEFINE_GRP = r'\b(?:def|class)[ \t]+\w+'
      
          #: A regexp that matches Python prompts
          PROMPT_RE = re.compile('(%s|%s)' % (_PROMPT1_GRP, _PROMPT2_GRP),
                                 re.MULTILINE | re.DOTALL)
      
          #: A regexp that matches Python "..." prompts.
          PROMPT2_RE = re.compile('(%s)' % _PROMPT2_GRP,
                                  re.MULTILINE | re.DOTALL)
      
          #: A regexp that matches doctest exception blocks.
          EXCEPT_RE = re.compile(r'^[ \t]*Traceback \(most recent call last\):.*',
                                 re.DOTALL | re.MULTILINE)
      
          #: A regexp that matches doctest directives.
          DOCTEST_DIRECTIVE_RE = re.compile(r'#[ \t]*doctest:.*')
      
          #: A regexp that matches all of the regions of a doctest block
          #: that should be colored.
          DOCTEST_RE = re.compile(
              r'(.*?)((?P%s)|(?P%s)|(?P%s)|'
                    r'(?P%s)|(?P%s)|'
                    r'(?P%s)|(?P%s)|(?P\Z))' % (
              _STRING_GRP, _COMMENT_GRP, _DEFINE_GRP, _KEYWORD_GRP, _BUILTIN_GRP,
              _PROMPT1_GRP, _PROMPT2_GRP), re.MULTILINE | re.DOTALL)
      
          #: This regular expression is used to find doctest examples in a
          #: string.  This is copied from the standard Python doctest.py
          #: module (after the refactoring in Python 2.4+).
          DOCTEST_EXAMPLE_RE = re.compile(r'''
              # Source consists of a PS1 line followed by zero or more PS2 lines.
              (?P
                  (?:^(?P [ ]*) >>>    .*)    # PS1 line
                  (?:\n           [ ]*  \.\.\. .*)*   # PS2 lines
                \n?)
              # Want consists of any non-blank lines that do not start with PS1.
              (?P (?:(?![ ]*$)    # Not a blank line
                           (?![ ]*>>>)  # Not a line starting with PS1
                           .*$\n?       # But any other line
                        )*)
              ''', re.MULTILINE | re.VERBOSE)
      
          def colorize_inline(self, s):
              """
              Colorize a string containing Python code.  Do not add the
              L{PREFIX} and L{SUFFIX} strings to the returned value.  This
              method is intended for generating syntax-highlighted strings
              that are appropriate for inclusion as inline expressions.
              """
              return self.DOCTEST_RE.sub(self.subfunc, s)
      
          def colorize_codeblock(self, s):
              """
              Colorize a string containing only Python code.  This method
              differs from L{colorize_doctest} in that it will not search
              for doctest prompts when deciding how to colorize the string.
              """
              body = self.DOCTEST_RE.sub(self.subfunc, s)
              return self.PREFIX + body + self.SUFFIX
      
          def colorize_doctest(self, s, strip_directives=False):
              """
              Colorize a string containing one or more doctest examples.
              """
              output = []
              charno = 0
              for m in self.DOCTEST_EXAMPLE_RE.finditer(s):
                  # Parse the doctest example:
                  pysrc, want = m.group('source', 'want')
                  # Pre-example text:
                  output.append(s[charno:m.start()])
                  # Example source code:
                  output.append(self.DOCTEST_RE.sub(self.subfunc, pysrc))
                  # Example output:
                  if want:
                      if self.EXCEPT_RE.match(want):
                          output += '\n'.join([self.markup(line, 'except')
                                               for line in want.split('\n')])
                      else:
                          output += '\n'.join([self.markup(line, 'output')
                                               for line in want.split('\n')])
                  # Update charno
                  charno = m.end()
              # Add any remaining post-example text.
              output.append(s[charno:])
              
              return self.PREFIX + ''.join(output) + self.SUFFIX
          
          def subfunc(self, match):
              other, text = match.group(1, 2)
              #print 'M %20r %20r' % (other, text) # <- for debugging
              if other:
                  other = '\n'.join([self.markup(line, 'other')
                                     for line in other.split('\n')])
                  
              if match.group('PROMPT1'):
                  return other + self.markup(text, 'prompt')
              elif match.group('PROMPT2'):
                  return other + self.markup(text, 'more')
              elif match.group('KEYWORD'):
                  return other + self.markup(text, 'keyword')
              elif match.group('BUILTIN'):
                  return other + self.markup(text, 'builtin')
              elif match.group('COMMENT'):
                  return other + self.markup(text, 'comment')
              elif match.group('STRING') and '\n' not in text:
                  return other + self.markup(text, 'string')
              elif match.group('STRING'):
                  # It's a multiline string; colorize the string & prompt
                  # portion of each line.
                  pieces = []
                  for line in text.split('\n'):
                      if self.PROMPT2_RE.match(line):
                          if len(line) > 4:
                              pieces.append(self.markup(line[:4], 'more') +
                                            self.markup(line[4:], 'string'))
                          else:
                              pieces.append(self.markup(line[:4], 'more'))
                      elif line:
                          pieces.append(self.markup(line, 'string'))
                      else:
                          pieces.append('')
                  return other + '\n'.join(pieces)
              elif match.group('DEFINE'):
                  m = re.match('(?P\w+)(?P\s+)(?P\w+)', text)
                  return other + (self.markup(m.group('def'), 'keyword') +
                              self.markup(m.group('space'), 'other') +
                              self.markup(m.group('name'), 'defname'))
              elif match.group('EOS') is not None:
                  return other
              else:
                  assert 0, 'Unexpected match!'
      
          def markup(self, s, tag):
              """
              Apply syntax highlighting to a single substring from a doctest
              block.  C{s} is the substring, and C{tag} is the tag that
              should be applied to the substring.  C{tag} will be one of the
              following strings:
              
                - C{prompt} -- the Python PS1 prompt (>>>)
                - C{more} -- the Python PS2 prompt (...)
                - C{keyword} -- a Python keyword (for, if, etc.)
                - C{builtin} -- a Python builtin name (abs, dir, etc.)
                - C{string} -- a string literal
                - C{comment} -- a comment
                - C{except} -- an exception traceback (up to the next >>>)
                - C{output} -- the output from a doctest block.
                - C{defname} -- the name of a function or class defined by
                  a C{def} or C{class} statement.
                - C{other} -- anything else (does *not* include output.)
              """
              raise AssertionError("Abstract method")
      
      class XMLDoctestColorizer(DoctestColorizer):
          """
          A subclass of DoctestColorizer that generates XML-like output.
          This class is mainly intended to be used for testing purposes.
          """
          PREFIX = '\n'
          SUFFIX = '\n'
          def markup(self, s, tag):
              s = s.replace('&', '&').replace('<', '<').replace('>', '>')
              if tag == 'other': return s
              else: return '<%s>%s' % (tag, s, tag)
      
      class HTMLDoctestColorizer(DoctestColorizer):
          """A subclass of DoctestColorizer that generates HTML output."""
          PREFIX = '
      \n'
          SUFFIX = '
      \n' def markup(self, s, tag): if tag == 'other': return plaintext_to_html(s) else: return ('%s' % (tag, plaintext_to_html(s))) class LaTeXDoctestColorizer(DoctestColorizer): """A subclass of DoctestColorizer that generates LaTeX output.""" PREFIX = '\\begin{alltt}\n' SUFFIX = '\\end{alltt}\n' def markup(self, s, tag): if tag == 'other': return plaintext_to_latex(s) else: return '\\pysrc%s{%s}' % (tag, plaintext_to_latex(s)) epydoc-3.0.1+dfsg/epydoc/markup/pyval_repr.py0000644000175000017500000005356610675540202021534 0ustar pronovicpronovic# epydoc -- Marked-up Representations for Python Values # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: apidoc.py 1448 2007-02-11 00:05:34Z dvarrazzo $ """ Syntax highlighter for Python values. Currently provides special colorization support for: - lists, tuples, sets, frozensets, dicts - numbers - strings - compiled regexps The highlighter also takes care of line-wrapping, and automatically stops generating repr output as soon as it has exceeded the specified number of lines (which should make it faster than pprint for large values). It does I{not} bother to do automatic cycle detection, because maxlines is typically around 5, so it's really not worth it. The syntax-highlighted output is encoded using a L{ParsedEpytextDocstring}, which can then be used to generate output in a variety of formats. """ __docformat__ = 'epytext en' # Implementation note: we use exact tests for classes (list, etc) # rather than using isinstance, because subclasses might override # __repr__. import types, re import epydoc.apidoc from epydoc.util import decode_with_backslashreplace from epydoc.util import plaintext_to_html, plaintext_to_latex from epydoc.compat import * import sre_parse, sre_constants from epydoc.markup.epytext import Element, ParsedEpytextDocstring def is_re_pattern(pyval): return type(pyval).__name__ == 'SRE_Pattern' class _ColorizerState: """ An object uesd to keep track of the current state of the pyval colorizer. The L{mark()}/L{restore()} methods can be used to set a backup point, and restore back to that backup point. This is used by several colorization methods that first try colorizing their object on a single line (setting linebreakok=False); and then fall back on a multi-line output if that fails. The L{score} variable is used to keep track of a 'score', reflecting how good we think this repr is. E.g., unhelpful values like '' get low scores. If the score is too low, we'll use the parse-derived repr instead. """ def __init__(self): self.result = [] self.charpos = 0 self.lineno = 1 self.linebreakok = True #: How good this represention is? self.score = 0 def mark(self): return (len(self.result), self.charpos, self.lineno, self.linebreakok, self.score) def restore(self, mark): n, self.charpos, self.lineno, self.linebreakok, self.score = mark del self.result[n:] class _Maxlines(Exception): """A control-flow exception that is raised when PyvalColorizer exeeds the maximum number of allowed lines.""" class _Linebreak(Exception): """A control-flow exception that is raised when PyvalColorizer generates a string containing a newline, but the state object's linebreakok variable is False.""" class ColorizedPyvalRepr(ParsedEpytextDocstring): """ @ivar score: A score, evaluating how good this repr is. @ivar is_complete: True if this colorized repr completely describes the object. """ def __init__(self, tree, score, is_complete): ParsedEpytextDocstring.__init__(self, tree) self.score = score self.is_complete = is_complete def colorize_pyval(pyval, parse_repr=None, min_score=None, linelen=75, maxlines=5, linebreakok=True, sort=True): return PyvalColorizer(linelen, maxlines, linebreakok, sort).colorize( pyval, parse_repr, min_score) class PyvalColorizer: """ Syntax highlighter for Python values. """ def __init__(self, linelen=75, maxlines=5, linebreakok=True, sort=True): self.linelen = linelen self.maxlines = maxlines self.linebreakok = linebreakok self.sort = sort #//////////////////////////////////////////////////////////// # Colorization Tags & other constants #//////////////////////////////////////////////////////////// GROUP_TAG = 'variable-group' # e.g., "[" and "]" COMMA_TAG = 'variable-op' # The "," that separates elements COLON_TAG = 'variable-op' # The ":" in dictionaries CONST_TAG = None # None, True, False NUMBER_TAG = None # ints, floats, etc QUOTE_TAG = 'variable-quote' # Quotes around strings. STRING_TAG = 'variable-string' # Body of string literals RE_CHAR_TAG = None RE_GROUP_TAG = 're-group' RE_REF_TAG = 're-ref' RE_OP_TAG = 're-op' RE_FLAGS_TAG = 're-flags' ELLIPSIS = Element('code', u'...', style='variable-ellipsis') LINEWRAP = Element('symbol', u'crarr') UNKNOWN_REPR = Element('code', u'??', style='variable-unknown') GENERIC_OBJECT_RE = re.compile(r'^<.* at 0x[0-9a-f]+>$', re.IGNORECASE) ESCAPE_UNICODE = False # should we escape non-ascii unicode chars? #//////////////////////////////////////////////////////////// # Entry Point #//////////////////////////////////////////////////////////// def colorize(self, pyval, parse_repr=None, min_score=None): """ @return: A L{ColorizedPyvalRepr} describing the given pyval. """ UNKNOWN = epydoc.apidoc.UNKNOWN # Create an object to keep track of the colorization. state = _ColorizerState() state.linebreakok = self.linebreakok # Colorize the value. If we reach maxlines, then add on an # ellipsis marker and call it a day. try: if pyval is not UNKNOWN: self._colorize(pyval, state) elif parse_repr not in (None, UNKNOWN): self._output(parse_repr, None, state) else: state.result.append(PyvalColorizer.UNKNOWN_REPR) is_complete = True except (_Maxlines, _Linebreak): if self.linebreakok: state.result.append('\n') state.result.append(self.ELLIPSIS) else: if state.result[-1] is self.LINEWRAP: state.result.pop() self._trim_result(state.result, 3) state.result.append(self.ELLIPSIS) is_complete = False # If we didn't score high enough, then try again. if (pyval is not UNKNOWN and parse_repr not in (None, UNKNOWN) and min_score is not None and state.score < min_score): return self.colorize(UNKNOWN, parse_repr) # Put it all together. tree = Element('epytext', *state.result) return ColorizedPyvalRepr(tree, state.score, is_complete) def _colorize(self, pyval, state): pyval_type = type(pyval) state.score += 1 if pyval is None or pyval is True or pyval is False: self._output(unicode(pyval), self.CONST_TAG, state) elif pyval_type in (int, float, long, types.ComplexType): self._output(unicode(pyval), self.NUMBER_TAG, state) elif pyval_type is str: self._colorize_str(pyval, state, '', 'string-escape') elif pyval_type is unicode: if self.ESCAPE_UNICODE: self._colorize_str(pyval, state, 'u', 'unicode-escape') else: self._colorize_str(pyval, state, 'u', None) elif pyval_type is list: self._multiline(self._colorize_iter, pyval, state, '[', ']') elif pyval_type is tuple: self._multiline(self._colorize_iter, pyval, state, '(', ')') elif pyval_type is set: self._multiline(self._colorize_iter, self._sort(pyval), state, 'set([', '])') elif pyval_type is frozenset: self._multiline(self._colorize_iter, self._sort(pyval), state, 'frozenset([', '])') elif pyval_type is dict: self._multiline(self._colorize_dict, self._sort(pyval.items()), state, '{', '}') elif is_re_pattern(pyval): self._colorize_re(pyval, state) else: try: pyval_repr = repr(pyval) if not isinstance(pyval_repr, (str, unicode)): pyval_repr = unicode(pyval_repr) pyval_repr_ok = True except KeyboardInterrupt: raise except: pyval_repr_ok = False state.score -= 100 if pyval_repr_ok: if self.GENERIC_OBJECT_RE.match(pyval_repr): state.score -= 5 self._output(pyval_repr, None, state) else: state.result.append(self.UNKNOWN_REPR) def _sort(self, items): if not self.sort: return items try: return sorted(items) except KeyboardInterrupt: raise except: return items def _trim_result(self, result, num_chars): while num_chars > 0: if not result: return if isinstance(result[-1], Element): assert len(result[-1].children) == 1 trim = min(num_chars, len(result[-1].children[0])) result[-1].children[0] = result[-1].children[0][:-trim] if not result[-1].children[0]: result.pop() num_chars -= trim else: trim = min(num_chars, len(result[-1])) result[-1] = result[-1][:-trim] if not result[-1]: result.pop() num_chars -= trim #//////////////////////////////////////////////////////////// # Object Colorization Functions #//////////////////////////////////////////////////////////// def _multiline(self, func, pyval, state, *args): """ Helper for container-type colorizers. First, try calling C{func(pyval, state, *args)} with linebreakok set to false; and if that fails, then try again with it set to true. """ linebreakok = state.linebreakok mark = state.mark() try: state.linebreakok = False func(pyval, state, *args) state.linebreakok = linebreakok except _Linebreak: if not linebreakok: raise state.restore(mark) func(pyval, state, *args) def _colorize_iter(self, pyval, state, prefix, suffix): self._output(prefix, self.GROUP_TAG, state) indent = state.charpos for i, elt in enumerate(pyval): if i>=1: if state.linebreakok: self._output(',', self.COMMA_TAG, state) self._output('\n'+' '*indent, None, state) else: self._output(', ', self.COMMA_TAG, state) self._colorize(elt, state) self._output(suffix, self.GROUP_TAG, state) def _colorize_dict(self, items, state, prefix, suffix): self._output(prefix, self.GROUP_TAG, state) indent = state.charpos for i, (key, val) in enumerate(items): if i>=1: if state.linebreakok: self._output(',', self.COMMA_TAG, state) self._output('\n'+' '*indent, None, state) else: self._output(', ', self.COMMA_TAG, state) self._colorize(key, state) self._output(': ', self.COLON_TAG, state) self._colorize(val, state) self._output(suffix, self.GROUP_TAG, state) def _colorize_str(self, pyval, state, prefix, encoding): # Decide which quote to use. if '\n' in pyval and state.linebreakok: quote = "'''" else: quote = "'" # Divide the string into lines. if state.linebreakok: lines = pyval.split('\n') else: lines = [pyval] # Open quote. self._output(prefix+quote, self.QUOTE_TAG, state) # Body for i, line in enumerate(lines): if i>0: self._output('\n', None, state) if encoding: line = line.encode(encoding) self._output(line, self.STRING_TAG, state) # Close quote. self._output(quote, self.QUOTE_TAG, state) def _colorize_re(self, pyval, state): # Extract the flag & pattern from the regexp. pat, flags = pyval.pattern, pyval.flags # If the pattern is a string, decode it to unicode. if isinstance(pat, str): pat = decode_with_backslashreplace(pat) # Parse the regexp pattern. tree = sre_parse.parse(pat, flags) groups = dict([(num,name) for (name,num) in tree.pattern.groupdict.items()]) # Colorize it! self._output("re.compile(r'", None, state) self._colorize_re_flags(tree.pattern.flags, state) self._colorize_re_tree(tree, state, True, groups) self._output("')", None, state) def _colorize_re_flags(self, flags, state): if flags: flags = [c for (c,n) in sorted(sre_parse.FLAGS.items()) if (n&flags)] flags = '(?%s)' % ''.join(flags) self._output(flags, self.RE_FLAGS_TAG, state) def _colorize_re_tree(self, tree, state, noparen, groups): assert noparen in (True, False) if len(tree) > 1 and not noparen: self._output('(', self.RE_GROUP_TAG, state) for elt in tree: op = elt[0] args = elt[1] if op == sre_constants.LITERAL: c = unichr(args) # Add any appropriate escaping. if c in '.^$\\*+?{}[]|()\'': c = '\\'+c elif c == '\t': c = '\\t' elif c == '\r': c = '\\r' elif c == '\n': c = '\\n' elif c == '\f': c = '\\f' elif c == '\v': c = '\\v' elif ord(c) > 0xffff: c = r'\U%08x' % ord(c) elif ord(c) > 0xff: c = r'\u%04x' % ord(c) elif ord(c)<32 or ord(c)>=127: c = r'\x%02x' % ord(c) self._output(c, self.RE_CHAR_TAG, state) elif op == sre_constants.ANY: self._output('.', self.RE_CHAR_TAG, state) elif op == sre_constants.BRANCH: if args[0] is not None: raise ValueError('Branch expected None arg but got %s' % args[0]) for i, item in enumerate(args[1]): if i > 0: self._output('|', self.RE_OP_TAG, state) self._colorize_re_tree(item, state, True, groups) elif op == sre_constants.IN: if (len(args) == 1 and args[0][0] == sre_constants.CATEGORY): self._colorize_re_tree(args, state, False, groups) else: self._output('[', self.RE_GROUP_TAG, state) self._colorize_re_tree(args, state, True, groups) self._output(']', self.RE_GROUP_TAG, state) elif op == sre_constants.CATEGORY: if args == sre_constants.CATEGORY_DIGIT: val = r'\d' elif args == sre_constants.CATEGORY_NOT_DIGIT: val = r'\D' elif args == sre_constants.CATEGORY_SPACE: val = r'\s' elif args == sre_constants.CATEGORY_NOT_SPACE: val = r'\S' elif args == sre_constants.CATEGORY_WORD: val = r'\w' elif args == sre_constants.CATEGORY_NOT_WORD: val = r'\W' else: raise ValueError('Unknown category %s' % args) self._output(val, self.RE_CHAR_TAG, state) elif op == sre_constants.AT: if args == sre_constants.AT_BEGINNING_STRING: val = r'\A' elif args == sre_constants.AT_BEGINNING: val = r'^' elif args == sre_constants.AT_END: val = r'$' elif args == sre_constants.AT_BOUNDARY: val = r'\b' elif args == sre_constants.AT_NON_BOUNDARY: val = r'\B' elif args == sre_constants.AT_END_STRING: val = r'\Z' else: raise ValueError('Unknown position %s' % args) self._output(val, self.RE_CHAR_TAG, state) elif op in (sre_constants.MAX_REPEAT, sre_constants.MIN_REPEAT): minrpt = args[0] maxrpt = args[1] if maxrpt == sre_constants.MAXREPEAT: if minrpt == 0: val = '*' elif minrpt == 1: val = '+' else: val = '{%d,}' % (minrpt) elif minrpt == 0: if maxrpt == 1: val = '?' else: val = '{,%d}' % (maxrpt) elif minrpt == maxrpt: val = '{%d}' % (maxrpt) else: val = '{%d,%d}' % (minrpt, maxrpt) if op == sre_constants.MIN_REPEAT: val += '?' self._colorize_re_tree(args[2], state, False, groups) self._output(val, self.RE_OP_TAG, state) elif op == sre_constants.SUBPATTERN: if args[0] is None: self._output('(?:', self.RE_GROUP_TAG, state) elif args[0] in groups: self._output('(?P<', self.RE_GROUP_TAG, state) self._output(groups[args[0]], self.RE_REF_TAG, state) self._output('>', self.RE_GROUP_TAG, state) elif isinstance(args[0], (int, long)): # This is cheating: self._output('(', self.RE_GROUP_TAG, state) else: self._output('(?P<', self.RE_GROUP_TAG, state) self._output(args[0], self.RE_REF_TAG, state) self._output('>', self.RE_GROUP_TAG, state) self._colorize_re_tree(args[1], state, True, groups) self._output(')', self.RE_GROUP_TAG, state) elif op == sre_constants.GROUPREF: self._output('\\%d' % args, self.RE_REF_TAG, state) elif op == sre_constants.RANGE: self._colorize_re_tree( ((sre_constants.LITERAL, args[0]),), state, False, groups ) self._output('-', self.RE_OP_TAG, state) self._colorize_re_tree( ((sre_constants.LITERAL, args[1]),), state, False, groups ) elif op == sre_constants.NEGATE: self._output('^', self.RE_OP_TAG, state) elif op == sre_constants.ASSERT: if args[0] > 0: self._output('(?=', self.RE_GROUP_TAG, state) else: self._output('(?<=', self.RE_GROUP_TAG, state) self._colorize_re_tree(args[1], state, True, groups) self._output(')', self.RE_GROUP_TAG, state) elif op == sre_constants.ASSERT_NOT: if args[0] > 0: self._output('(?!', self.RE_GROUP_TAG, state) else: self._output('(? 1 and not noparen: self._output(')', self.RE_GROUP_TAG, state) #//////////////////////////////////////////////////////////// # Output function #//////////////////////////////////////////////////////////// def _output(self, s, tag, state): """ Add the string `s` to the result list, tagging its contents with tag `tag`. Any lines that go beyond `self.linelen` will be line-wrapped. If the total number of lines exceeds `self.maxlines`, then raise a `_Maxlines` exception. """ # Make sure the string is unicode. if isinstance(s, str): s = decode_with_backslashreplace(s) # Split the string into segments. The first segment is the # content to add to the current line, and the remaining # segments are new lines. segments = s.split('\n') for i, segment in enumerate(segments): # If this isn't the first segment, then add a newline to # split it from the previous segment. if i > 0: if (state.lineno+1) > self.maxlines: raise _Maxlines() if not state.linebreakok: raise _Linebreak() state.result.append(u'\n') state.lineno += 1 state.charpos = 0 # If the segment fits on the current line, then just call # markup to tag it, and store the result. if state.charpos + len(segment) <= self.linelen: state.charpos += len(segment) if tag: segment = Element('code', segment, style=tag) state.result.append(segment) # If the segment doesn't fit on the current line, then # line-wrap it, and insert the remainder of the line into # the segments list that we're iterating over. (We'll go # the the beginning of the next line at the start of the # next iteration through the loop.) else: split = self.linelen-state.charpos segments.insert(i+1, segment[split:]) segment = segment[:split] if tag: segment = Element('code', segment, style=tag) state.result += [segment, self.LINEWRAP] epydoc-3.0.1+dfsg/epydoc/markup/__init__.py0000644000175000017500000005513110675377761021120 0ustar pronovicpronovic# # epydoc package file # # A python documentation Module # Edward Loper # # $Id: __init__.py 1577 2007-03-09 23:26:21Z dvarrazzo $ # """ Markup language support for docstrings. Each submodule defines a parser for a single markup language. These parsers convert an object's docstring to a L{ParsedDocstring}, a standard intermediate representation that can be used to generate output. C{ParsedDocstring}s support the following operations: - output generation (L{to_plaintext()}, L{to_html()}, and L{to_latex()}). - Summarization (L{summary()}). - Field extraction (L{split_fields()}). - Index term extraction (L{index_terms()}. The L{parse()} function provides a single interface to the C{epydoc.markup} package: it takes a docstring and the name of a markup language; delegates to the appropriate parser; and returns the parsed docstring (along with any errors or warnings that were generated). The C{ParsedDocstring} output generation methods (C{to_M{format}()}) use a L{DocstringLinker} to link the docstring output with the rest of the documentation that epydoc generates. C{DocstringLinker}s are currently responsible for translating two kinds of crossreference: - index terms (L{translate_indexterm() }). - identifier crossreferences (L{translate_identifier_xref() }). A parsed docstring's fields can be extracted using the L{ParsedDocstring.split_fields()} method. This method divides a docstring into its main body and a list of L{Field}s, each of which encodes a single field. The field's bodies are encoded as C{ParsedDocstring}s. Markup errors are represented using L{ParseError}s. These exception classes record information about the cause, location, and severity of each error. @sort: parse, ParsedDocstring, Field, DocstringLinker @group Errors and Warnings: ParseError @group Utility Functions: parse_type_of @var SCRWIDTH: The default width with which text will be wrapped when formatting the output of the parser. @type SCRWIDTH: C{int} @var _parse_warnings: Used by L{_parse_warn}. """ __docformat__ = 'epytext en' import re, types, sys from epydoc import log from epydoc.util import plaintext_to_html, plaintext_to_latex import epydoc from epydoc.compat import * ################################################## ## Contents ################################################## # # 1. parse() dispatcher # 2. ParsedDocstring abstract base class # 3. Field class # 4. Docstring Linker # 5. ParseError exceptions # 6. Misc helpers # ################################################## ## Dispatcher ################################################## _markup_language_registry = { 'restructuredtext': 'epydoc.markup.restructuredtext', 'epytext': 'epydoc.markup.epytext', 'plaintext': 'epydoc.markup.plaintext', 'javadoc': 'epydoc.markup.javadoc', } def register_markup_language(name, parse_function): """ Register a new markup language named C{name}, which can be parsed by the function C{parse_function}. @param name: The name of the markup language. C{name} should be a simple identifier, such as C{'epytext'} or C{'restructuredtext'}. Markup language names are case insensitive. @param parse_function: A function which can be used to parse the markup language, and returns a L{ParsedDocstring}. It should have the following signature: >>> def parse(s, errors): ... 'returns a ParsedDocstring' Where: - C{s} is the string to parse. (C{s} will be a unicode string.) - C{errors} is a list; any errors that are generated during docstring parsing should be appended to this list (as L{ParseError} objects). """ _markup_language_registry[name.lower()] = parse_function MARKUP_LANGUAGES_USED = set() def parse(docstring, markup='plaintext', errors=None, **options): """ Parse the given docstring, and use it to construct a C{ParsedDocstring}. If any fatal C{ParseError}s are encountered while parsing the docstring, then the docstring will be rendered as plaintext, instead. @type docstring: C{string} @param docstring: The docstring to encode. @type markup: C{string} @param markup: The name of the markup language that is used by the docstring. If the markup language is not supported, then the docstring will be treated as plaintext. The markup name is case-insensitive. @param errors: A list where any errors generated during parsing will be stored. If no list is specified, then fatal errors will generate exceptions, and non-fatal errors will be ignored. @type errors: C{list} of L{ParseError} @rtype: L{ParsedDocstring} @return: A L{ParsedDocstring} that encodes the contents of C{docstring}. @raise ParseError: If C{errors} is C{None} and an error is encountered while parsing. """ # Initialize errors list. raise_on_error = (errors is None) if errors == None: errors = [] # Normalize the markup language name. markup = markup.lower() # Is the markup language valid? if not re.match(r'\w+', markup): _parse_warn('Bad markup language name %r. Treating ' 'docstrings as plaintext.' % markup) import epydoc.markup.plaintext as plaintext return plaintext.parse_docstring(docstring, errors, **options) # Is the markup language supported? if markup not in _markup_language_registry: _parse_warn('Unsupported markup language %r. Treating ' 'docstrings as plaintext.' % markup) import epydoc.markup.plaintext as plaintext return plaintext.parse_docstring(docstring, errors, **options) # Get the parse function. parse_docstring = _markup_language_registry[markup] # If it's a string, then it names a function to import. if isinstance(parse_docstring, basestring): try: exec('from %s import parse_docstring' % parse_docstring) except ImportError, e: _parse_warn('Error importing %s for markup language %s: %s' % (parse_docstring, markup, e)) import epydoc.markup.plaintext as plaintext return plaintext.parse_docstring(docstring, errors, **options) _markup_language_registry[markup] = parse_docstring # Keep track of which markup languages have been used so far. MARKUP_LANGUAGES_USED.add(markup) # Parse the docstring. try: parsed_docstring = parse_docstring(docstring, errors, **options) except KeyboardInterrupt: raise except Exception, e: if epydoc.DEBUG: raise log.error('Internal error while parsing a docstring: %s; ' 'treating docstring as plaintext' % e) import epydoc.markup.plaintext as plaintext return plaintext.parse_docstring(docstring, errors, **options) # Check for fatal errors. fatal_errors = [e for e in errors if e.is_fatal()] if fatal_errors and raise_on_error: raise fatal_errors[0] if fatal_errors: import epydoc.markup.plaintext as plaintext return plaintext.parse_docstring(docstring, errors, **options) return parsed_docstring # only issue each warning once: _parse_warnings = {} def _parse_warn(estr): """ Print a warning message. If the given error has already been printed, then do nothing. """ global _parse_warnings if estr in _parse_warnings: return _parse_warnings[estr] = 1 log.warning(estr) ################################################## ## ParsedDocstring ################################################## class ParsedDocstring: """ A standard intermediate representation for parsed docstrings that can be used to generate output. Parsed docstrings are produced by markup parsers (such as L{epytext.parse} or L{javadoc.parse}). C{ParsedDocstring}s support several kinds of operation: - output generation (L{to_plaintext()}, L{to_html()}, and L{to_latex()}). - Summarization (L{summary()}). - Field extraction (L{split_fields()}). - Index term extraction (L{index_terms()}. The output generation methods (C{to_M{format}()}) use a L{DocstringLinker} to link the docstring output with the rest of the documentation that epydoc generates. Subclassing =========== The only method that a subclass is I{required} to implement is L{to_plaintext()}; but it is often useful to override the other methods. The default behavior of each method is described below: - C{to_I{format}}: Calls C{to_plaintext}, and uses the string it returns to generate verbatim output. - C{summary}: Returns C{self} (i.e., the entire docstring). - C{split_fields}: Returns C{(self, [])} (i.e., extracts no fields). - C{index_terms}: Returns C{[]} (i.e., extracts no index terms). If and when epydoc adds more output formats, new C{to_I{format}} methods will be added to this base class; but they will always be given a default implementation. """ def split_fields(self, errors=None): """ Split this docstring into its body and its fields. @return: A tuple C{(M{body}, M{fields})}, where C{M{body}} is the main body of this docstring, and C{M{fields}} is a list of its fields. If the resulting body is empty, return C{None} for the body. @rtype: C{(L{ParsedDocstring}, list of L{Field})} @param errors: A list where any errors generated during splitting will be stored. If no list is specified, then errors will be ignored. @type errors: C{list} of L{ParseError} """ # Default behavior: return self, [] def summary(self): """ @return: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring. @rtype: (L{ParsedDocstring}, C{bool}) """ # Default behavior: return self, False def concatenate(self, other): """ @return: A new parsed docstring containing the concatination of this docstring and C{other}. @raise ValueError: If the two parsed docstrings are incompatible. """ return ConcatenatedDocstring(self, other) def __add__(self, other): return self.concatenate(other) def to_html(self, docstring_linker, **options): """ Translate this docstring to HTML. @param docstring_linker: An HTML translator for crossreference links into and out of the docstring. @type docstring_linker: L{DocstringLinker} @param options: Any extra options for the output. Unknown options are ignored. @return: An HTML fragment that encodes this docstring. @rtype: C{string} """ # Default behavior: plaintext = plaintext_to_html(self.to_plaintext(docstring_linker)) return '
      \n%s\n
      \n' % plaintext def to_latex(self, docstring_linker, **options): """ Translate this docstring to LaTeX. @param docstring_linker: A LaTeX translator for crossreference links into and out of the docstring. @type docstring_linker: L{DocstringLinker} @param options: Any extra options for the output. Unknown options are ignored. @return: A LaTeX fragment that encodes this docstring. @rtype: C{string} """ # Default behavior: plaintext = plaintext_to_latex(self.to_plaintext(docstring_linker)) return '\\begin{alltt}\n%s\\end{alltt}\n\n' % plaintext def to_plaintext(self, docstring_linker, **options): """ Translate this docstring to plaintext. @param docstring_linker: A plaintext translator for crossreference links into and out of the docstring. @type docstring_linker: L{DocstringLinker} @param options: Any extra options for the output. Unknown options are ignored. @return: A plaintext fragment that encodes this docstring. @rtype: C{string} """ raise NotImplementedError, 'ParsedDocstring.to_plaintext()' def index_terms(self): """ @return: The list of index terms that are defined in this docstring. Each of these items will be added to the index page of the documentation. @rtype: C{list} of C{ParsedDocstring} """ # Default behavior: return [] ################################################## ## Concatenated Docstring ################################################## class ConcatenatedDocstring: def __init__(self, *parsed_docstrings): self._parsed_docstrings = [pds for pds in parsed_docstrings if pds is not None] def split_fields(self, errors=None): bodies = [] fields = [] for doc in self._parsed_docstrings: b,f = doc.split_fields() bodies.append(b) fields.extend(f) return ConcatenatedDocstring(*bodies), fields def summary(self): return self._parsed_docstrings[0].summary() def to_html(self, docstring_linker, **options): htmlstring = '' for doc in self._parsed_docstrings: htmlstring += doc.to_html(docstring_linker, **options) return htmlstring def to_latex(self, docstring_linker, **options): latexstring = '' for doc in self._parsed_docstrings: latexstring += doc.to_latex(docstring_linker, **options) return latexstring def to_plaintext(self, docstring_linker, **options): textstring = '' for doc in self._parsed_docstrings: textstring += doc.to_plaintext(docstring_linker, **options) return textstring def index_terms(self): terms = [] for doc in self._parsed_docstrings: terms += doc.index_terms() return terms ################################################## ## Fields ################################################## class Field: """ The contents of a docstring's field. Docstring fields are used to describe specific aspects of an object, such as a parameter of a function or the author of a module. Each field consists of a tag, an optional argument, and a body: - The tag specifies the type of information that the field encodes. - The argument specifies the object that the field describes. The argument may be C{None} or a C{string}. - The body contains the field's information. Tags are automatically downcased and stripped; and arguments are automatically stripped. """ def __init__(self, tag, arg, body): self._tag = tag.lower().strip() if arg is None: self._arg = None else: self._arg = arg.strip() self._body = body def tag(self): """ @return: This field's tag. @rtype: C{string} """ return self._tag def arg(self): """ @return: This field's argument, or C{None} if this field has no argument. @rtype: C{string} or C{None} """ return self._arg def body(self): """ @return: This field's body. @rtype: L{ParsedDocstring} """ return self._body def __repr__(self): if self._arg is None: return '' % self._tag else: return '' % (self._tag, self._arg) ################################################## ## Docstring Linker (resolves crossreferences) ################################################## class DocstringLinker: """ A translator for crossreference links into and out of a C{ParsedDocstring}. C{DocstringLinker} is used by C{ParsedDocstring} to convert these crossreference links into appropriate output formats. For example, C{DocstringLinker.to_html} expects a C{DocstringLinker} that converts crossreference links to HTML. """ def translate_indexterm(self, indexterm): """ Translate an index term to the appropriate output format. The output will typically include a crossreference anchor. @type indexterm: L{ParsedDocstring} @param indexterm: The index term to translate. @rtype: C{string} @return: The translated index term. """ raise NotImplementedError, 'DocstringLinker.translate_indexterm()' def translate_identifier_xref(self, identifier, label=None): """ Translate a crossreference link to a Python identifier to the appropriate output format. The output will typically include a reference or pointer to the crossreference target. @type identifier: C{string} @param identifier: The name of the Python identifier that should be linked to. @type label: C{string} or C{None} @param label: The label that should be used for the identifier, if it's different from the name of the identifier. @rtype: C{string} @return: The translated crossreference link. """ raise NotImplementedError, 'DocstringLinker.translate_xref()' ################################################## ## ParseError exceptions ################################################## class ParseError(Exception): """ The base class for errors generated while parsing docstrings. @ivar _linenum: The line on which the error occured within the docstring. The linenum of the first line is 0. @type _linenum: C{int} @ivar _offset: The line number where the docstring begins. This offset is added to C{_linenum} when displaying the line number of the error. Default value: 1. @type _offset: C{int} @ivar _descr: A description of the error. @type _descr: C{string} @ivar _fatal: True if this is a fatal error. @type _fatal: C{boolean} """ def __init__(self, descr, linenum=None, is_fatal=1): """ @type descr: C{string} @param descr: A description of the error. @type linenum: C{int} @param linenum: The line on which the error occured within the docstring. The linenum of the first line is 0. @type is_fatal: C{boolean} @param is_fatal: True if this is a fatal error. """ self._descr = descr self._linenum = linenum self._fatal = is_fatal self._offset = 1 def is_fatal(self): """ @return: true if this is a fatal error. If an error is fatal, then epydoc should ignore the output of the parser, and parse the docstring as plaintext. @rtype: C{boolean} """ return self._fatal def linenum(self): """ @return: The line number on which the error occured (including any offset). If the line number is unknown, then return C{None}. @rtype: C{int} or C{None} """ if self._linenum is None: return None else: return self._offset + self._linenum def set_linenum_offset(self, offset): """ Set the line number offset for this error. This offset is the line number where the docstring begins. This offset is added to C{_linenum} when displaying the line number of the error. @param offset: The new line number offset. @type offset: C{int} @rtype: C{None} """ self._offset = offset def descr(self): return self._descr def __str__(self): """ Return a string representation of this C{ParseError}. This multi-line string contains a description of the error, and specifies where it occured. @return: the informal representation of this C{ParseError}. @rtype: C{string} """ if self._linenum is not None: return 'Line %s: %s' % (self._linenum+self._offset, self.descr()) else: return self.descr() def __repr__(self): """ Return the formal representation of this C{ParseError}. C{ParseError}s have formal representations of the form:: @return: the formal representation of this C{ParseError}. @rtype: C{string} """ if self._linenum is None: return '' % (self._linenum+self._offset) def __cmp__(self, other): """ Compare two C{ParseError}s, based on their line number. - Return -1 if C{self.linenumother.linenum} - Return 0 if C{self.linenum==other.linenum}. The return value is undefined if C{other} is not a ParseError. @rtype: C{int} """ if not isinstance(other, ParseError): return -1000 return cmp(self._linenum+self._offset, other._linenum+other._offset) ################################################## ## Misc helpers ################################################## # These are used by multiple markup parsers def parse_type_of(obj): """ @return: A C{ParsedDocstring} that encodes the type of the given object. @rtype: L{ParsedDocstring} @param obj: The object whose type should be returned as DOM document. @type obj: any """ # This is a bit hackish; oh well. :) from epydoc.markup.epytext import ParsedEpytextDocstring from xml.dom.minidom import Document doc = Document() epytext = doc.createElement('epytext') para = doc.createElement('para') doc.appendChild(epytext) epytext.appendChild(para) if type(obj) is types.InstanceType: link = doc.createElement('link') name = doc.createElement('name') target = doc.createElement('target') para.appendChild(link) link.appendChild(name) link.appendChild(target) name.appendChild(doc.createTextNode(str(obj.__class__.__name__))) target.appendChild(doc.createTextNode(str(obj.__class__))) else: code = doc.createElement('code') para.appendChild(code) code.appendChild(doc.createTextNode(type(obj).__name__)) return ParsedEpytextDocstring(doc) epydoc-3.0.1+dfsg/epydoc/markup/restructuredtext.py0000644000175000017500000010733510747415705023014 0ustar pronovicpronovic# # rst.py: ReStructuredText docstring parsing # Edward Loper # # Created [06/28/03 02:52 AM] # $Id: restructuredtext.py 1661 2007-11-07 12:59:34Z dvarrazzo $ # """ Epydoc parser for ReStructuredText strings. ReStructuredText is the standard markup language used by the Docutils project. L{parse_docstring()} provides the primary interface to this module; it returns a L{ParsedRstDocstring}, which supports all of the methods defined by L{ParsedDocstring}. L{ParsedRstDocstring} is basically just a L{ParsedDocstring} wrapper for the C{docutils.nodes.document} class. Creating C{ParsedRstDocstring}s =============================== C{ParsedRstDocstring}s are created by the C{parse_document} function, using the C{docutils.core.publish_string()} method, with the following helpers: - An L{_EpydocReader} is used to capture all error messages as it parses the docstring. - A L{_DocumentPseudoWriter} is used to extract the document itself, without actually writing any output. The document is saved for further processing. The settings for the writer are copied from C{docutils.writers.html4css1.Writer}, since those settings will be used when we actually write the docstring to html. Using C{ParsedRstDocstring}s ============================ C{ParsedRstDocstring}s support all of the methods defined by C{ParsedDocstring}; but only the following four methods have non-default behavior: - L{to_html()} uses an L{_EpydocHTMLTranslator} to translate the C{ParsedRstDocstring}'s document into an HTML segment. - L{split_fields()} uses a L{_SplitFieldsTranslator} to divide the C{ParsedRstDocstring}'s document into its main body and its fields. Special handling is done to account for consolidated fields. - L{summary()} uses a L{_SummaryExtractor} to extract the first sentence from the C{ParsedRstDocstring}'s document. - L{to_plaintext()} uses C{document.astext()} to convert the C{ParsedRstDocstring}'s document to plaintext. @todo: Add ParsedRstDocstring.to_latex() @var CONSOLIDATED_FIELDS: A dictionary encoding the set of 'consolidated fields' that can be used. Each consolidated field is marked by a single tag, and contains a single bulleted list, where each list item starts with an identifier, marked as interpreted text (C{`...`}). This module automatically splits these consolidated fields into individual fields. The keys of C{CONSOLIDATED_FIELDS} are the names of possible consolidated fields; and the values are the names of the field tags that should be used for individual entries in the list. """ __docformat__ = 'epytext en' # Imports import re, os, os.path from xml.dom.minidom import * from docutils.core import publish_string from docutils.writers import Writer from docutils.writers.html4css1 import HTMLTranslator, Writer as HTMLWriter from docutils.writers.latex2e import LaTeXTranslator, Writer as LaTeXWriter from docutils.readers.standalone import Reader as StandaloneReader from docutils.utils import new_document from docutils.nodes import NodeVisitor, Text, SkipChildren from docutils.nodes import SkipNode, TreeCopyVisitor from docutils.frontend import OptionParser from docutils.parsers.rst import directives, roles import docutils.nodes import docutils.transforms.frontmatter import docutils.transforms import docutils.utils from epydoc.compat import * # Backwards compatibility from epydoc.markup import * from epydoc.apidoc import ModuleDoc, ClassDoc from epydoc.docwriter.dotgraph import * from epydoc.docwriter.xlink import ApiLinkReader from epydoc.markup.doctest import doctest_to_html, doctest_to_latex, \ HTMLDoctestColorizer #: A dictionary whose keys are the "consolidated fields" that are #: recognized by epydoc; and whose values are the corresponding epydoc #: field names that should be used for the individual fields. CONSOLIDATED_FIELDS = { 'parameters': 'param', 'arguments': 'arg', 'exceptions': 'except', 'variables': 'var', 'ivariables': 'ivar', 'cvariables': 'cvar', 'groups': 'group', 'types': 'type', 'keywords': 'keyword', } #: A list of consolidated fields whose bodies may be specified using a #: definition list, rather than a bulleted list. For these fields, the #: 'classifier' for each term in the definition list is translated into #: a @type field. CONSOLIDATED_DEFLIST_FIELDS = ['param', 'arg', 'var', 'ivar', 'cvar', 'keyword'] def parse_docstring(docstring, errors, **options): """ Parse the given docstring, which is formatted using ReStructuredText; and return a L{ParsedDocstring} representation of its contents. @param docstring: The docstring to parse @type docstring: C{string} @param errors: A list where any errors generated during parsing will be stored. @type errors: C{list} of L{ParseError} @param options: Extra options. Unknown options are ignored. Currently, no extra options are defined. @rtype: L{ParsedDocstring} """ writer = _DocumentPseudoWriter() reader = _EpydocReader(errors) # Outputs errors to the list. publish_string(docstring, writer=writer, reader=reader, settings_overrides={'report_level':10000, 'halt_level':10000, 'warning_stream':None}) return ParsedRstDocstring(writer.document) class OptimizedReporter(docutils.utils.Reporter): """A reporter that ignores all debug messages. This is used to shave a couple seconds off of epydoc's run time, since docutils isn't very fast about processing its own debug messages.""" def debug(self, *args, **kwargs): pass class ParsedRstDocstring(ParsedDocstring): """ An encoded version of a ReStructuredText docstring. The contents of the docstring are encoded in the L{_document} instance variable. @ivar _document: A ReStructuredText document, encoding the docstring. @type _document: C{docutils.nodes.document} """ def __init__(self, document): """ @type document: C{docutils.nodes.document} """ self._document = document # The default document reporter and transformer are not # pickle-able; so replace them with stubs that are. document.reporter = OptimizedReporter( document.reporter.source, 'SEVERE', 'SEVERE', '') document.transformer = docutils.transforms.Transformer(document) def split_fields(self, errors=None): # Inherit docs if errors is None: errors = [] visitor = _SplitFieldsTranslator(self._document, errors) self._document.walk(visitor) if len(self._document.children) > 0: return self, visitor.fields else: return None, visitor.fields def summary(self): # Inherit docs visitor = _SummaryExtractor(self._document) try: self._document.walk(visitor) except docutils.nodes.NodeFound: pass return visitor.summary, bool(visitor.other_docs) # def concatenate(self, other): # result = self._document.copy() # for child in (self._document.get_children() + # other._document.get_children()): # visitor = TreeCopyVisitor(self._document) # child.walkabout(visitor) # result.append(visitor.get_tree_copy()) # return ParsedRstDocstring(result) def to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options): # Inherit docs visitor = _EpydocHTMLTranslator(self._document, docstring_linker, directory, docindex, context) self._document.walkabout(visitor) return ''.join(visitor.body) def to_latex(self, docstring_linker, **options): # Inherit docs visitor = _EpydocLaTeXTranslator(self._document, docstring_linker) self._document.walkabout(visitor) return ''.join(visitor.body) def to_plaintext(self, docstring_linker, **options): # This is should be replaced by something better: return self._document.astext() def __repr__(self): return '' def index_terms(self): visitor = _TermsExtractor(self._document) self._document.walkabout(visitor) return visitor.terms class _EpydocReader(ApiLinkReader): """ A reader that captures all errors that are generated by parsing, and appends them to a list. """ # Remove the DocInfo transform, to ensure that :author: fields are # correctly handled. This needs to be handled differently # depending on the version of docutils that's being used, because # the default_transforms attribute was deprecated & replaced by # get_transforms(). version = [int(v) for v in docutils.__version__.split('.')] version += [ 0 ] * (3 - len(version)) if version < [0,4,0]: default_transforms = list(ApiLinkReader.default_transforms) try: default_transforms.remove(docutils.transforms.frontmatter.DocInfo) except ValueError: pass else: def get_transforms(self): return [t for t in ApiLinkReader.get_transforms(self) if t != docutils.transforms.frontmatter.DocInfo] del version def __init__(self, errors): self._errors = errors ApiLinkReader.__init__(self) def new_document(self): document = new_document(self.source.source_path, self.settings) # Capture all warning messages. document.reporter.attach_observer(self.report) # These are used so we know how to encode warning messages: self._encoding = document.reporter.encoding self._error_handler = document.reporter.error_handler # Return the new document. return document def report(self, error): try: is_fatal = int(error['level']) > 2 except: is_fatal = 1 try: linenum = int(error['line']) except: linenum = None msg = ''.join([c.astext().encode(self._encoding, self._error_handler) for c in error]) self._errors.append(ParseError(msg, linenum, is_fatal)) class _DocumentPseudoWriter(Writer): """ A pseudo-writer for the docutils framework, that can be used to access the document itself. The output of C{_DocumentPseudoWriter} is just an empty string; but after it has been used, the most recently processed document is available as the instance variable C{document} @type document: C{docutils.nodes.document} @ivar document: The most recently processed document. """ def __init__(self): self.document = None Writer.__init__(self) def translate(self): self.output = '' class _SummaryExtractor(NodeVisitor): """ A docutils node visitor that extracts the first sentence from the first paragraph in a document. """ def __init__(self, document): NodeVisitor.__init__(self, document) self.summary = None self.other_docs = None def visit_document(self, node): self.summary = None _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)') def visit_paragraph(self, node): if self.summary is not None: # found a paragraph after the first one self.other_docs = True raise docutils.nodes.NodeFound('Found summary') summary_pieces = [] # Extract the first sentence. for child in node: if isinstance(child, docutils.nodes.Text): m = self._SUMMARY_RE.match(child.data) if m: summary_pieces.append(docutils.nodes.Text(m.group(1))) other = child.data[m.end():] if other and not other.isspace(): self.other_docs = True break summary_pieces.append(child) summary_doc = self.document.copy() # shallow copy summary_para = node.copy() # shallow copy summary_doc[:] = [summary_para] summary_para[:] = summary_pieces self.summary = ParsedRstDocstring(summary_doc) def visit_field(self, node): raise SkipNode def unknown_visit(self, node): 'Ignore all unknown nodes' class _TermsExtractor(NodeVisitor): """ A docutils node visitor that extracts the terms from documentation. Terms are created using the C{:term:} interpreted text role. """ def __init__(self, document): NodeVisitor.__init__(self, document) self.terms = None """ The terms currently found. @type: C{list} """ def visit_document(self, node): self.terms = [] self._in_term = False def visit_emphasis(self, node): if 'term' in node.get('classes'): self._in_term = True def depart_emphasis(self, node): if 'term' in node.get('classes'): self._in_term = False def visit_Text(self, node): if self._in_term: doc = self.document.copy() doc[:] = [node.copy()] self.terms.append(ParsedRstDocstring(doc)) def unknown_visit(self, node): 'Ignore all unknown nodes' def unknown_departure(self, node): 'Ignore all unknown nodes' class _SplitFieldsTranslator(NodeVisitor): """ A docutils translator that removes all fields from a document, and collects them into the instance variable C{fields} @ivar fields: The fields of the most recently walked document. @type fields: C{list} of L{Field} """ ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD = True """If true, then consolidated fields are not required to mark arguments with C{`backticks`}. (This is currently only implemented for consolidated fields expressed as definition lists; consolidated fields expressed as unordered lists still require backticks for now.""" def __init__(self, document, errors): NodeVisitor.__init__(self, document) self._errors = errors self.fields = [] self._newfields = {} def visit_document(self, node): self.fields = [] def visit_field(self, node): # Remove the field from the tree. node.parent.remove(node) # Extract the field name & optional argument tag = node[0].astext().split(None, 1) tagname = tag[0] if len(tag)>1: arg = tag[1] else: arg = None # Handle special fields: fbody = node[1] if arg is None: for (list_tag, entry_tag) in CONSOLIDATED_FIELDS.items(): if tagname.lower() == list_tag: try: self.handle_consolidated_field(fbody, entry_tag) return except ValueError, e: estr = 'Unable to split consolidated field ' estr += '"%s" - %s' % (tagname, e) self._errors.append(ParseError(estr, node.line, is_fatal=0)) # Use a @newfield to let it be displayed as-is. if tagname.lower() not in self._newfields: newfield = Field('newfield', tagname.lower(), parse(tagname, 'plaintext')) self.fields.append(newfield) self._newfields[tagname.lower()] = 1 self._add_field(tagname, arg, fbody) def _add_field(self, tagname, arg, fbody): field_doc = self.document.copy() for child in fbody: field_doc.append(child) field_pdoc = ParsedRstDocstring(field_doc) self.fields.append(Field(tagname, arg, field_pdoc)) def visit_field_list(self, node): # Remove the field list from the tree. The visitor will still walk # over the node's children. node.parent.remove(node) def handle_consolidated_field(self, body, tagname): """ Attempt to handle a consolidated section. """ if len(body) != 1: raise ValueError('does not contain a single list.') elif body[0].tagname == 'bullet_list': self.handle_consolidated_bullet_list(body[0], tagname) elif (body[0].tagname == 'definition_list' and tagname in CONSOLIDATED_DEFLIST_FIELDS): self.handle_consolidated_definition_list(body[0], tagname) elif tagname in CONSOLIDATED_DEFLIST_FIELDS: raise ValueError('does not contain a bulleted list or ' 'definition list.') else: raise ValueError('does not contain a bulleted list.') def handle_consolidated_bullet_list(self, items, tagname): # Check the contents of the list. In particular, each list # item should have the form: # - `arg`: description... n = 0 _BAD_ITEM = ("list item %d is not well formed. Each item must " "consist of a single marked identifier (e.g., `x`), " "optionally followed by a colon or dash and a " "description.") for item in items: n += 1 if item.tagname != 'list_item' or len(item) == 0: raise ValueError('bad bulleted list (bad child %d).' % n) if item[0].tagname != 'paragraph': if item[0].tagname == 'definition_list': raise ValueError(('list item %d contains a definition '+ 'list (it\'s probably indented '+ 'wrong).') % n) else: raise ValueError(_BAD_ITEM % n) if len(item[0]) == 0: raise ValueError(_BAD_ITEM % n) if item[0][0].tagname != 'title_reference': raise ValueError(_BAD_ITEM % n) # Everything looks good; convert to multiple fields. for item in items: # Extract the arg arg = item[0][0].astext() # Extract the field body, and remove the arg fbody = item[:] fbody[0] = fbody[0].copy() fbody[0][:] = item[0][1:] # Remove the separating ":", if present if (len(fbody[0]) > 0 and isinstance(fbody[0][0], docutils.nodes.Text)): child = fbody[0][0] if child.data[:1] in ':-': child.data = child.data[1:].lstrip() elif child.data[:2] in (' -', ' :'): child.data = child.data[2:].lstrip() # Wrap the field body, and add a new field self._add_field(tagname, arg, fbody) def handle_consolidated_definition_list(self, items, tagname): # Check the list contents. n = 0 _BAD_ITEM = ("item %d is not well formed. Each item's term must " "consist of a single marked identifier (e.g., `x`), " "optionally followed by a space, colon, space, and " "a type description.") for item in items: n += 1 if (item.tagname != 'definition_list_item' or len(item) < 2 or item[0].tagname != 'term' or item[-1].tagname != 'definition'): raise ValueError('bad definition list (bad child %d).' % n) if len(item) > 3: raise ValueError(_BAD_ITEM % n) if not ((item[0][0].tagname == 'title_reference') or (self.ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD and isinstance(item[0][0], docutils.nodes.Text))): raise ValueError(_BAD_ITEM % n) for child in item[0][1:]: if child.astext() != '': raise ValueError(_BAD_ITEM % n) # Extract it. for item in items: # The basic field. arg = item[0][0].astext() fbody = item[-1] self._add_field(tagname, arg, fbody) # If there's a classifier, treat it as a type. if len(item) == 3: type_descr = item[1] self._add_field('type', arg, type_descr) def unknown_visit(self, node): 'Ignore all unknown nodes' def latex_head_prefix(): document = new_document('') translator = _EpydocLaTeXTranslator(document, None) return translator.head_prefix class _EpydocLaTeXTranslator(LaTeXTranslator): settings = None def __init__(self, document, docstring_linker): # Set the document's settings. if self.settings is None: settings = OptionParser([LaTeXWriter()]).get_default_values() settings.output_encoding = 'utf-8' self.__class__.settings = settings document.settings = self.settings LaTeXTranslator.__init__(self, document) self._linker = docstring_linker # Start at section level 3. (Unfortunately, we now have to # set a private variable to make this work; perhaps the standard # latex translator should grow an official way to spell this?) self.section_level = 3 self._section_number = [0]*self.section_level # Handle interpreted text (crossreferences) def visit_title_reference(self, node): target = self.encode(node.astext()) xref = self._linker.translate_identifier_xref(target, target) self.body.append(xref) raise SkipNode() def visit_document(self, node): pass def depart_document(self, node): pass # For now, just ignore dotgraphs. [XXX] def visit_dotgraph(self, node): log.warning("Ignoring dotgraph in latex output (dotgraph " "rendering for latex not implemented yet).") raise SkipNode() def visit_doctest_block(self, node): self.body.append(doctest_to_latex(node[0].astext())) raise SkipNode() class _EpydocHTMLTranslator(HTMLTranslator): settings = None def __init__(self, document, docstring_linker, directory, docindex, context): self._linker = docstring_linker self._directory = directory self._docindex = docindex self._context = context # Set the document's settings. if self.settings is None: settings = OptionParser([HTMLWriter()]).get_default_values() self.__class__.settings = settings document.settings = self.settings # Call the parent constructor. HTMLTranslator.__init__(self, document) # Handle interpreted text (crossreferences) def visit_title_reference(self, node): target = self.encode(node.astext()) xref = self._linker.translate_identifier_xref(target, target) self.body.append(xref) raise SkipNode() def should_be_compact_paragraph(self, node): if self.document.children == [node]: return True else: return HTMLTranslator.should_be_compact_paragraph(self, node) def visit_document(self, node): pass def depart_document(self, node): pass def starttag(self, node, tagname, suffix='\n', **attributes): """ This modified version of starttag makes a few changes to HTML tags, to prevent them from conflicting with epydoc. In particular: - existing class attributes are prefixed with C{'rst-'} - existing names are prefixed with C{'rst-'} - hrefs starting with C{'#'} are prefixed with C{'rst-'} - hrefs not starting with C{'#'} are given target='_top' - all headings (C{}) are given the css class C{'heading'} """ # Get the list of all attribute dictionaries we need to munge. attr_dicts = [attributes] if isinstance(node, docutils.nodes.Node): attr_dicts.append(node.attributes) if isinstance(node, dict): attr_dicts.append(node) # Munge each attribute dictionary. Unfortunately, we need to # iterate through attributes one at a time because some # versions of docutils don't case-normalize attributes. for attr_dict in attr_dicts: for (key, val) in attr_dict.items(): # Prefix all CSS classes with "rst-"; and prefix all # names with "rst-" to avoid conflicts. if key.lower() in ('class', 'id', 'name'): attr_dict[key] = 'rst-%s' % val elif key.lower() in ('classes', 'ids', 'names'): attr_dict[key] = ['rst-%s' % cls for cls in val] elif key.lower() == 'href': if attr_dict[key][:1]=='#': attr_dict[key] = '#rst-%s' % attr_dict[key][1:] else: # If it's an external link, open it in a new # page. attr_dict['target'] = '_top' # For headings, use class="heading" if re.match(r'^h\d+$', tagname): attributes['class'] = ' '.join([attributes.get('class',''), 'heading']).strip() return HTMLTranslator.starttag(self, node, tagname, suffix, **attributes) def visit_dotgraph(self, node): if self._directory is None: return # [xx] warning? # Generate the graph. graph = node.graph(self._docindex, self._context, self._linker) if graph is None: return # Write the graph. image_url = '%s.gif' % graph.uid image_file = os.path.join(self._directory, image_url) self.body.append(graph.to_html(image_file, image_url)) raise SkipNode() def visit_doctest_block(self, node): pysrc = node[0].astext() if node.get('codeblock'): self.body.append(HTMLDoctestColorizer().colorize_codeblock(pysrc)) else: self.body.append(doctest_to_html(pysrc)) raise SkipNode() def visit_emphasis(self, node): # Generate a corrent index term anchor if 'term' in node.get('classes') and node.children: doc = self.document.copy() doc[:] = [node.children[0].copy()] self.body.append( self._linker.translate_indexterm(ParsedRstDocstring(doc))) raise SkipNode() HTMLTranslator.visit_emphasis(self, node) def python_code_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ A custom restructuredtext directive which can be used to display syntax-highlighted Python code blocks. This directive takes no arguments, and the body should contain only Python code. This directive can be used instead of doctest blocks when it is inconvenient to list prompts on each line, or when you would prefer that the output not contain prompts (e.g., to make copy/paste easier). """ required_arguments = 0 optional_arguments = 0 text = '\n'.join(content) node = docutils.nodes.doctest_block(text, text, codeblock=True) return [ node ] python_code_directive.arguments = (0, 0, 0) python_code_directive.content = True directives.register_directive('python', python_code_directive) def term_role(name, rawtext, text, lineno, inliner, options={}, content=[]): text = docutils.utils.unescape(text) node = docutils.nodes.emphasis(rawtext, text, **options) node.attributes['classes'].append('term') return [node], [] roles.register_local_role('term', term_role) ###################################################################### #{ Graph Generation Directives ###################################################################### # See http://docutils.sourceforge.net/docs/howto/rst-directives.html class dotgraph(docutils.nodes.image): """ A custom docutils node that should be rendered using Graphviz dot. This node does not directly store the graph; instead, it stores a pointer to a function that can be used to generate the graph. This allows the graph to be built based on information that might not be available yet at parse time. This graph generation function has the following signature: >>> def generate_graph(docindex, context, linker, *args): ... 'generates and returns a new DotGraph' Where C{docindex} is a docindex containing the documentation that epydoc has built; C{context} is the C{APIDoc} whose docstring contains this dotgraph node; C{linker} is a L{DocstringLinker} that can be used to resolve crossreferences; and C{args} is any extra arguments that are passed to the C{dotgraph} constructor. """ def __init__(self, generate_graph_func, *generate_graph_args): docutils.nodes.image.__init__(self) self.graph_func = generate_graph_func self.args = generate_graph_args def graph(self, docindex, context, linker): return self.graph_func(docindex, context, linker, *self.args) def _dir_option(argument): """A directive option spec for the orientation of a graph.""" argument = argument.lower().strip() if argument == 'right': return 'LR' if argument == 'left': return 'RL' if argument == 'down': return 'TB' if argument == 'up': return 'BT' raise ValueError('%r unknown; choose from left, right, up, down' % argument) def digraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ A custom restructuredtext directive which can be used to display Graphviz dot graphs. This directive takes a single argument, which is used as the graph's name. The contents of the directive are used as the body of the graph. Any href attributes whose value has the form will be replaced by the URL of the object with that name. Here's a simple example:: .. digraph:: example_digraph a -> b -> c c -> a [dir=\"none\"] """ if arguments: title = arguments[0] else: title = '' return [ dotgraph(_construct_digraph, title, options.get('caption'), '\n'.join(content)) ] digraph_directive.arguments = (0, 1, True) digraph_directive.options = {'caption': directives.unchanged} digraph_directive.content = True directives.register_directive('digraph', digraph_directive) def _construct_digraph(docindex, context, linker, title, caption, body): """Graph generator for L{digraph_directive}""" graph = DotGraph(title, body, caption=caption) graph.link(linker) return graph def classtree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ A custom restructuredtext directive which can be used to graphically display a class hierarchy. If one or more arguments are given, then those classes and all their descendants will be displayed. If no arguments are given, and the directive is in a class's docstring, then that class and all its descendants will be displayed. It is an error to use this directive with no arguments in a non-class docstring. Options: - C{:dir:} -- Specifies the orientation of the graph. One of C{down}, C{right} (default), C{left}, C{up}. """ return [ dotgraph(_construct_classtree, arguments, options) ] classtree_directive.arguments = (0, 1, True) classtree_directive.options = {'dir': _dir_option} classtree_directive.content = False directives.register_directive('classtree', classtree_directive) def _construct_classtree(docindex, context, linker, arguments, options): """Graph generator for L{classtree_directive}""" if len(arguments) == 1: bases = [docindex.find(name, context) for name in arguments[0].replace(',',' ').split()] bases = [d for d in bases if isinstance(d, ClassDoc)] elif isinstance(context, ClassDoc): bases = [context] else: log.warning("Could not construct class tree: you must " "specify one or more base classes.") return None return class_tree_graph(bases, linker, context, **options) def packagetree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): """ A custom restructuredtext directive which can be used to graphically display a package hierarchy. If one or more arguments are given, then those packages and all their submodules will be displayed. If no arguments are given, and the directive is in a package's docstring, then that package and all its submodules will be displayed. It is an error to use this directive with no arguments in a non-package docstring. Options: - C{:dir:} -- Specifies the orientation of the graph. One of C{down}, C{right} (default), C{left}, C{up}. """ return [ dotgraph(_construct_packagetree, arguments, options) ] packagetree_directive.arguments = (0, 1, True) packagetree_directive.options = { 'dir': _dir_option, 'style': lambda a:directives.choice(a.lower(), ('uml', 'tree'))} packagetree_directive.content = False directives.register_directive('packagetree', packagetree_directive) def _construct_packagetree(docindex, context, linker, arguments, options): """Graph generator for L{packagetree_directive}""" if len(arguments) == 1: packages = [docindex.find(name, context) for name in arguments[0].replace(',',' ').split()] packages = [d for d in packages if isinstance(d, ModuleDoc)] elif isinstance(context, ModuleDoc): packages = [context] else: log.warning("Could not construct package tree: you must " "specify one or more root packages.") return None return package_tree_graph(packages, linker, context, **options) def importgraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): return [ dotgraph(_construct_importgraph, arguments, options) ] importgraph_directive.arguments = (0, 1, True) importgraph_directive.options = {'dir': _dir_option} importgraph_directive.content = False directives.register_directive('importgraph', importgraph_directive) def _construct_importgraph(docindex, context, linker, arguments, options): """Graph generator for L{importgraph_directive}""" if len(arguments) == 1: modules = [ docindex.find(name, context) for name in arguments[0].replace(',',' ').split() ] modules = [d for d in modules if isinstance(d, ModuleDoc)] else: modules = [d for d in docindex.root if isinstance(d, ModuleDoc)] return import_graph(modules, docindex, linker, context, **options) def callgraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine): return [ dotgraph(_construct_callgraph, arguments, options) ] callgraph_directive.arguments = (0, 1, True) callgraph_directive.options = {'dir': _dir_option, 'add_callers': directives.flag, 'add_callees': directives.flag} callgraph_directive.content = False directives.register_directive('callgraph', callgraph_directive) def _construct_callgraph(docindex, context, linker, arguments, options): """Graph generator for L{callgraph_directive}""" if len(arguments) == 1: docs = [docindex.find(name, context) for name in arguments[0].replace(',',' ').split()] docs = [doc for doc in docs if doc is not None] else: docs = [context] return call_graph(docs, docindex, linker, context, **options) epydoc-3.0.1+dfsg/epydoc/markup/epytext.py0000644000175000017500000024341610676361757021067 0ustar pronovicpronovic# # epytext.py: epydoc formatted docstring parsing # Edward Loper # # Created [04/10/01 12:00 AM] # $Id: epytext.py 1652 2007-09-26 04:45:34Z edloper $ # """ Parser for epytext strings. Epytext is a lightweight markup whose primary intended application is Python documentation strings. This parser converts Epytext strings to a simple DOM-like representation (encoded as a tree of L{Element} objects and strings). Epytext strings can contain the following X{structural blocks}: - X{epytext}: The top-level element of the DOM tree. - X{para}: A paragraph of text. Paragraphs contain no newlines, and all spaces are soft. - X{section}: A section or subsection. - X{field}: A tagged field. These fields provide information about specific aspects of a Python object, such as the description of a function's parameter, or the author of a module. - X{literalblock}: A block of literal text. This text should be displayed as it would be displayed in plaintext. The parser removes the appropriate amount of leading whitespace from each line in the literal block. - X{doctestblock}: A block containing sample python code, formatted according to the specifications of the C{doctest} module. - X{ulist}: An unordered list. - X{olist}: An ordered list. - X{li}: A list item. This tag is used both for unordered list items and for ordered list items. Additionally, the following X{inline regions} may be used within C{para} blocks: - X{code}: Source code and identifiers. - X{math}: Mathematical expressions. - X{index}: A term which should be included in an index, if one is generated. - X{italic}: Italicized text. - X{bold}: Bold-faced text. - X{uri}: A Universal Resource Indicator (URI) or Universal Resource Locator (URL) - X{link}: A Python identifier which should be hyperlinked to the named object's documentation, when possible. The returned DOM tree will conform to the the following Document Type Description:: @var SYMBOLS: A list of the of escape symbols that are supported by epydoc. Currently the following symbols are supported: <<>> """ # Note: the symbol list is appended to the docstring automatically, # below. __docformat__ = 'epytext en' # Code organization.. # 1. parse() # 2. tokenize() # 3. colorize() # 4. helpers # 5. testing import re, string, types, sys, os.path from epydoc.markup import * from epydoc.util import wordwrap, plaintext_to_html, plaintext_to_latex from epydoc.markup.doctest import doctest_to_html, doctest_to_latex ################################################## ## DOM-Like Encoding ################################################## class Element: """ A very simple DOM-like representation for parsed epytext documents. Each epytext document is encoded as a tree whose nodes are L{Element} objects, and whose leaves are C{string}s. Each node is marked by a I{tag} and zero or more I{attributes}. Each attribute is a mapping from a string key to a string value. """ def __init__(self, tag, *children, **attribs): self.tag = tag """A string tag indicating the type of this element. @type: C{string}""" self.children = list(children) """A list of the children of this element. @type: C{list} of (C{string} or C{Element})""" self.attribs = attribs """A dictionary mapping attribute names to attribute values for this element. @type: C{dict} from C{string} to C{string}""" def __str__(self): """ Return a string representation of this element, using XML notation. @bug: Doesn't escape '<' or '&' or '>'. """ attribs = ''.join([' %s=%r' % t for t in self.attribs.items()]) return ('<%s%s>' % (self.tag, attribs) + ''.join([str(child) for child in self.children]) + '' % self.tag) def __repr__(self): attribs = ''.join([', %s=%r' % t for t in self.attribs.items()]) args = ''.join([', %r' % c for c in self.children]) return 'Element(%s%s%s)' % (self.tag, args, attribs) ################################################## ## Constants ################################################## # The possible heading underline characters, listed in order of # heading depth. _HEADING_CHARS = "=-~" # Escape codes. These should be needed very rarely. _ESCAPES = {'lb':'{', 'rb': '}'} # Symbols. These can be generated via S{...} escapes. SYMBOLS = [ # Arrows '<-', '->', '^', 'v', # Greek letters 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 'nu', 'xi', 'omicron', 'pi', 'rho', 'sigma', 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega', 'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 'Tau', 'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega', # HTML character entities 'larr', 'rarr', 'uarr', 'darr', 'harr', 'crarr', 'lArr', 'rArr', 'uArr', 'dArr', 'hArr', 'copy', 'times', 'forall', 'exist', 'part', 'empty', 'isin', 'notin', 'ni', 'prod', 'sum', 'prop', 'infin', 'ang', 'and', 'or', 'cap', 'cup', 'int', 'there4', 'sim', 'cong', 'asymp', 'ne', 'equiv', 'le', 'ge', 'sub', 'sup', 'nsub', 'sube', 'supe', 'oplus', 'otimes', 'perp', # Alternate (long) names 'infinity', 'integral', 'product', '>=', '<=', ] # Convert to a dictionary, for quick lookup _SYMBOLS = {} for symbol in SYMBOLS: _SYMBOLS[symbol] = 1 # Add symbols to the docstring. symblist = ' ' symblist += ';\n '.join([' - C{E{S}{%s}}=S{%s}' % (symbol, symbol) for symbol in SYMBOLS]) __doc__ = __doc__.replace('<<>>', symblist) del symbol, symblist # Tags for colorizing text. _COLORIZING_TAGS = { 'C': 'code', 'M': 'math', 'X': 'indexed', 'I': 'italic', 'B': 'bold', 'U': 'uri', 'L': 'link', # A Python identifier that should be linked to 'E': 'escape', # escapes characters or creates symbols 'S': 'symbol', 'G': 'graph', } # Which tags can use "link syntax" (e.g., U{Python})? _LINK_COLORIZING_TAGS = ['link', 'uri'] ################################################## ## Structuring (Top Level) ################################################## def parse(str, errors = None): """ Return a DOM tree encoding the contents of an epytext string. Any errors generated during parsing will be stored in C{errors}. @param str: The epytext string to parse. @type str: C{string} @param errors: A list where any errors generated during parsing will be stored. If no list is specified, then fatal errors will generate exceptions, and non-fatal errors will be ignored. @type errors: C{list} of L{ParseError} @return: a DOM tree encoding the contents of an epytext string. @rtype: C{Element} @raise ParseError: If C{errors} is C{None} and an error is encountered while parsing. """ # Initialize errors list. if errors == None: errors = [] raise_on_error = 1 else: raise_on_error = 0 # Preprocess the string. str = re.sub('\015\012', '\012', str) str = string.expandtabs(str) # Tokenize the input string. tokens = _tokenize(str, errors) # Have we encountered a field yet? encountered_field = 0 # Create an document to hold the epytext. doc = Element('epytext') # Maintain two parallel stacks: one contains DOM elements, and # gives the ancestors of the current block. The other contains # indentation values, and gives the indentation of the # corresponding DOM elements. An indentation of "None" reflects # an unknown indentation. However, the indentation must be # greater than, or greater than or equal to, the indentation of # the prior element (depending on what type of DOM element it # corresponds to). No 2 consecutive indent_stack values will be # ever be "None." Use initial dummy elements in the stack, so we # don't have to worry about bounds checking. stack = [None, doc] indent_stack = [-1, None] for token in tokens: # Uncomment this for debugging: #print ('%s: %s\n%s: %s\n' % # (''.join(['%-11s' % (t and t.tag) for t in stack]), # token.tag, ''.join(['%-11s' % i for i in indent_stack]), # token.indent)) # Pop any completed blocks off the stack. _pop_completed_blocks(token, stack, indent_stack) # If Token has type PARA, colorize and add the new paragraph if token.tag == Token.PARA: _add_para(doc, token, stack, indent_stack, errors) # If Token has type HEADING, add the new section elif token.tag == Token.HEADING: _add_section(doc, token, stack, indent_stack, errors) # If Token has type LBLOCK, add the new literal block elif token.tag == Token.LBLOCK: stack[-1].children.append(token.to_dom(doc)) # If Token has type DTBLOCK, add the new doctest block elif token.tag == Token.DTBLOCK: stack[-1].children.append(token.to_dom(doc)) # If Token has type BULLET, add the new list/list item/field elif token.tag == Token.BULLET: _add_list(doc, token, stack, indent_stack, errors) else: assert 0, 'Unknown token type: '+token.tag # Check if the DOM element we just added was a field.. if stack[-1].tag == 'field': encountered_field = 1 elif encountered_field == 1: if len(stack) <= 3: estr = ("Fields must be the final elements in an "+ "epytext string.") errors.append(StructuringError(estr, token.startline)) # Graphs use inline markup (G{...}) but are really block-level # elements; so "raise" any graphs we generated. This is a bit of # a hack, but the alternative is to define a new markup for # block-level elements, which I'd rather not do. (See sourceforge # bug #1673017.) for child in doc.children: _raise_graphs(child, doc) # If there was an error, then signal it! if len([e for e in errors if e.is_fatal()]) > 0: if raise_on_error: raise errors[0] else: return None # Return the top-level epytext DOM element. return doc def _raise_graphs(tree, parent): # Recurse to children. have_graph_child = False for elt in tree.children: if isinstance(elt, Element): _raise_graphs(elt, tree) if elt.tag == 'graph': have_graph_child = True block = ('section', 'fieldlist', 'field', 'ulist', 'olist', 'li') if have_graph_child and tree.tag not in block: child_index = 0 for elt in tree.children: if isinstance(elt, Element) and elt.tag == 'graph': # We found a graph: splice it into the parent. parent_index = parent.children.index(tree) left = tree.children[:child_index] right = tree.children[child_index+1:] parent.children[parent_index:parent_index+1] = [ Element(tree.tag, *left, **tree.attribs), elt, Element(tree.tag, *right, **tree.attribs)] child_index = 0 parent_index += 2 else: child_index += 1 def _pop_completed_blocks(token, stack, indent_stack): """ Pop any completed blocks off the stack. This includes any blocks that we have dedented past, as well as any list item blocks that we've dedented to. The top element on the stack should only be a list if we're about to start a new list item (i.e., if the next token is a bullet). """ indent = token.indent if indent != None: while (len(stack) > 2): pop = 0 # Dedent past a block if indent_stack[-1]!=None and indent len(stack): estr = "Wrong underline character for heading." errors.append(StructuringError(estr, heading_token.startline)) # Pop the appropriate number of headings so we're at the # correct level. stack[heading_token.level+2:] = [] indent_stack[heading_token.level+2:] = [] # Colorize the heading head = _colorize(doc, heading_token, errors, 'heading') # Add the section's and heading's DOM elements. sec = Element("section") stack[-1].children.append(sec) stack.append(sec) sec.children.append(head) indent_stack.append(None) def _add_list(doc, bullet_token, stack, indent_stack, errors): """ Add a new list item or field to the DOM tree, with the given bullet or field tag. When necessary, create the associated list. """ # Determine what type of bullet it is. if bullet_token.contents[-1] == '-': list_type = 'ulist' elif bullet_token.contents[-1] == '.': list_type = 'olist' elif bullet_token.contents[-1] == ':': list_type = 'fieldlist' else: raise AssertionError('Bad Bullet: %r' % bullet_token.contents) # Is this a new list? newlist = 0 if stack[-1].tag != list_type: newlist = 1 elif list_type == 'olist' and stack[-1].tag == 'olist': old_listitem = stack[-1].children[-1] old_bullet = old_listitem.attribs.get("bullet").split('.')[:-1] new_bullet = bullet_token.contents.split('.')[:-1] if (new_bullet[:-1] != old_bullet[:-1] or int(new_bullet[-1]) != int(old_bullet[-1])+1): newlist = 1 # Create the new list. if newlist: if stack[-1].tag is 'fieldlist': # The new list item is not a field list item (since this # is a new list); but it's indented the same as the field # list. This either means that they forgot to indent the # list, or they are trying to put something after the # field list. The first one seems more likely, so we'll # just warn about that (to avoid confusion). estr = "Lists must be indented." errors.append(StructuringError(estr, bullet_token.startline)) if stack[-1].tag in ('ulist', 'olist', 'fieldlist'): stack.pop() indent_stack.pop() if (list_type != 'fieldlist' and indent_stack[-1] is not None and bullet_token.indent == indent_stack[-1]): # Ignore this error if there's text on the same line as # the comment-opening quote -- epydoc can't reliably # determine the indentation for that line. if bullet_token.startline != 1 or bullet_token.indent != 0: estr = "Lists must be indented." errors.append(StructuringError(estr, bullet_token.startline)) if list_type == 'fieldlist': # Fieldlist should be at the top-level. for tok in stack[2:]: if tok.tag != "section": estr = "Fields must be at the top level." errors.append( StructuringError(estr, bullet_token.startline)) break stack[2:] = [] indent_stack[2:] = [] # Add the new list. lst = Element(list_type) stack[-1].children.append(lst) stack.append(lst) indent_stack.append(bullet_token.indent) if list_type == 'olist': start = bullet_token.contents.split('.')[:-1] if start != '1': lst.attribs["start"] = start[-1] # Fields are treated somewhat specially: A "fieldlist" # node is created to make the parsing simpler, but fields # are adjoined directly into the "epytext" node, not into # the "fieldlist" node. if list_type == 'fieldlist': li = Element("field") token_words = bullet_token.contents[1:-1].split(None, 1) tag_elt = Element("tag") tag_elt.children.append(token_words[0]) li.children.append(tag_elt) if len(token_words) > 1: arg_elt = Element("arg") arg_elt.children.append(token_words[1]) li.children.append(arg_elt) else: li = Element("li") if list_type == 'olist': li.attribs["bullet"] = bullet_token.contents # Add the bullet. stack[-1].children.append(li) stack.append(li) indent_stack.append(None) ################################################## ## Tokenization ################################################## class Token: """ C{Token}s are an intermediate data structure used while constructing the structuring DOM tree for a formatted docstring. There are five types of C{Token}: - Paragraphs - Literal blocks - Doctest blocks - Headings - Bullets The text contained in each C{Token} is stored in the C{contents} variable. The string in this variable has been normalized. For paragraphs, this means that it has been converted into a single line of text, with newline/indentation replaced by single spaces. For literal blocks and doctest blocks, this means that the appropriate amount of leading whitespace has been removed from each line. Each C{Token} has an indentation level associated with it, stored in the C{indent} variable. This indentation level is used by the structuring procedure to assemble hierarchical blocks. @type tag: C{string} @ivar tag: This C{Token}'s type. Possible values are C{Token.PARA} (paragraph), C{Token.LBLOCK} (literal block), C{Token.DTBLOCK} (doctest block), C{Token.HEADINGC}, and C{Token.BULLETC}. @type startline: C{int} @ivar startline: The line on which this C{Token} begins. This line number is only used for issuing errors. @type contents: C{string} @ivar contents: The normalized text contained in this C{Token}. @type indent: C{int} or C{None} @ivar indent: The indentation level of this C{Token} (in number of leading spaces). A value of C{None} indicates an unknown indentation; this is used for list items and fields that begin with one-line paragraphs. @type level: C{int} or C{None} @ivar level: The heading-level of this C{Token} if it is a heading; C{None}, otherwise. Valid heading levels are 0, 1, and 2. @type inline: C{bool} @ivar inline: If True, the element is an inline level element, comparable to an HTML C{} tag. Else, it is a block level element, comparable to an HTML C{
      }. @type PARA: C{string} @cvar PARA: The C{tag} value for paragraph C{Token}s. @type LBLOCK: C{string} @cvar LBLOCK: The C{tag} value for literal C{Token}s. @type DTBLOCK: C{string} @cvar DTBLOCK: The C{tag} value for doctest C{Token}s. @type HEADING: C{string} @cvar HEADING: The C{tag} value for heading C{Token}s. @type BULLET: C{string} @cvar BULLET: The C{tag} value for bullet C{Token}s. This C{tag} value is also used for field tag C{Token}s, since fields function syntactically the same as list items. """ # The possible token types. PARA = "para" LBLOCK = "literalblock" DTBLOCK = "doctestblock" HEADING = "heading" BULLET = "bullet" def __init__(self, tag, startline, contents, indent, level=None, inline=False): """ Create a new C{Token}. @param tag: The type of the new C{Token}. @type tag: C{string} @param startline: The line on which the new C{Token} begins. @type startline: C{int} @param contents: The normalized contents of the new C{Token}. @type contents: C{string} @param indent: The indentation of the new C{Token} (in number of leading spaces). A value of C{None} indicates an unknown indentation. @type indent: C{int} or C{None} @param level: The heading-level of this C{Token} if it is a heading; C{None}, otherwise. @type level: C{int} or C{None} @param inline: Is this C{Token} inline as a C{}?. @type inline: C{bool} """ self.tag = tag self.startline = startline self.contents = contents self.indent = indent self.level = level self.inline = inline def __repr__(self): """ @rtype: C{string} @return: the formal representation of this C{Token}. C{Token}s have formal representaitons of the form:: """ return '' % (self.tag, self.startline) def to_dom(self, doc): """ @return: a DOM representation of this C{Token}. @rtype: L{Element} """ e = Element(self.tag) e.children.append(self.contents) return e # Construct regular expressions for recognizing bullets. These are # global so they don't have to be reconstructed each time we tokenize # a docstring. _ULIST_BULLET = '[-]( +|$)' _OLIST_BULLET = '(\d+[.])+( +|$)' _FIELD_BULLET = '@\w+( [^{}:\n]+)?:' _BULLET_RE = re.compile(_ULIST_BULLET + '|' + _OLIST_BULLET + '|' + _FIELD_BULLET) _LIST_BULLET_RE = re.compile(_ULIST_BULLET + '|' + _OLIST_BULLET) _FIELD_BULLET_RE = re.compile(_FIELD_BULLET) del _ULIST_BULLET, _OLIST_BULLET, _FIELD_BULLET def _tokenize_doctest(lines, start, block_indent, tokens, errors): """ Construct a L{Token} containing the doctest block starting at C{lines[start]}, and append it to C{tokens}. C{block_indent} should be the indentation of the doctest block. Any errors generated while tokenizing the doctest block will be appended to C{errors}. @param lines: The list of lines to be tokenized @param start: The index into C{lines} of the first line of the doctest block to be tokenized. @param block_indent: The indentation of C{lines[start]}. This is the indentation of the doctest block. @param errors: A list where any errors generated during parsing will be stored. If no list is specified, then errors will generate exceptions. @return: The line number of the first line following the doctest block. @type lines: C{list} of C{string} @type start: C{int} @type block_indent: C{int} @type tokens: C{list} of L{Token} @type errors: C{list} of L{ParseError} @rtype: C{int} """ # If they dedent past block_indent, keep track of the minimum # indentation. This is used when removing leading indentation # from the lines of the doctest block. min_indent = block_indent linenum = start + 1 while linenum < len(lines): # Find the indentation of this line. line = lines[linenum] indent = len(line) - len(line.lstrip()) # A blank line ends doctest block. if indent == len(line): break # A Dedent past block_indent is an error. if indent < block_indent: min_indent = min(min_indent, indent) estr = 'Improper doctest block indentation.' errors.append(TokenizationError(estr, linenum)) # Go on to the next line. linenum += 1 # Add the token, and return the linenum after the token ends. contents = [line[min_indent:] for line in lines[start:linenum]] contents = '\n'.join(contents) tokens.append(Token(Token.DTBLOCK, start, contents, block_indent)) return linenum def _tokenize_literal(lines, start, block_indent, tokens, errors): """ Construct a L{Token} containing the literal block starting at C{lines[start]}, and append it to C{tokens}. C{block_indent} should be the indentation of the literal block. Any errors generated while tokenizing the literal block will be appended to C{errors}. @param lines: The list of lines to be tokenized @param start: The index into C{lines} of the first line of the literal block to be tokenized. @param block_indent: The indentation of C{lines[start]}. This is the indentation of the literal block. @param errors: A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list. @return: The line number of the first line following the literal block. @type lines: C{list} of C{string} @type start: C{int} @type block_indent: C{int} @type tokens: C{list} of L{Token} @type errors: C{list} of L{ParseError} @rtype: C{int} """ linenum = start + 1 while linenum < len(lines): # Find the indentation of this line. line = lines[linenum] indent = len(line) - len(line.lstrip()) # A Dedent to block_indent ends the literal block. # (Ignore blank likes, though) if len(line) != indent and indent <= block_indent: break # Go on to the next line. linenum += 1 # Add the token, and return the linenum after the token ends. contents = [line[block_indent+1:] for line in lines[start:linenum]] contents = '\n'.join(contents) contents = re.sub('(\A[ \n]*\n)|(\n[ \n]*\Z)', '', contents) tokens.append(Token(Token.LBLOCK, start, contents, block_indent)) return linenum def _tokenize_listart(lines, start, bullet_indent, tokens, errors): """ Construct L{Token}s for the bullet and the first paragraph of the list item (or field) starting at C{lines[start]}, and append them to C{tokens}. C{bullet_indent} should be the indentation of the list item. Any errors generated while tokenizing will be appended to C{errors}. @param lines: The list of lines to be tokenized @param start: The index into C{lines} of the first line of the list item to be tokenized. @param bullet_indent: The indentation of C{lines[start]}. This is the indentation of the list item. @param errors: A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list. @return: The line number of the first line following the list item's first paragraph. @type lines: C{list} of C{string} @type start: C{int} @type bullet_indent: C{int} @type tokens: C{list} of L{Token} @type errors: C{list} of L{ParseError} @rtype: C{int} """ linenum = start + 1 para_indent = None doublecolon = lines[start].rstrip()[-2:] == '::' # Get the contents of the bullet. para_start = _BULLET_RE.match(lines[start], bullet_indent).end() bcontents = lines[start][bullet_indent:para_start].strip() while linenum < len(lines): # Find the indentation of this line. line = lines[linenum] indent = len(line) - len(line.lstrip()) # "::" markers end paragraphs. if doublecolon: break if line.rstrip()[-2:] == '::': doublecolon = 1 # A blank line ends the token if indent == len(line): break # Dedenting past bullet_indent ends the list item. if indent < bullet_indent: break # A line beginning with a bullet ends the token. if _BULLET_RE.match(line, indent): break # If this is the second line, set the paragraph indentation, or # end the token, as appropriate. if para_indent == None: para_indent = indent # A change in indentation ends the token if indent != para_indent: break # Go on to the next line. linenum += 1 # Add the bullet token. tokens.append(Token(Token.BULLET, start, bcontents, bullet_indent, inline=True)) # Add the paragraph token. pcontents = ([lines[start][para_start:].strip()] + [line.strip() for line in lines[start+1:linenum]]) pcontents = ' '.join(pcontents).strip() if pcontents: tokens.append(Token(Token.PARA, start, pcontents, para_indent, inline=True)) # Return the linenum after the paragraph token ends. return linenum def _tokenize_para(lines, start, para_indent, tokens, errors): """ Construct a L{Token} containing the paragraph starting at C{lines[start]}, and append it to C{tokens}. C{para_indent} should be the indentation of the paragraph . Any errors generated while tokenizing the paragraph will be appended to C{errors}. @param lines: The list of lines to be tokenized @param start: The index into C{lines} of the first line of the paragraph to be tokenized. @param para_indent: The indentation of C{lines[start]}. This is the indentation of the paragraph. @param errors: A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list. @return: The line number of the first line following the paragraph. @type lines: C{list} of C{string} @type start: C{int} @type para_indent: C{int} @type tokens: C{list} of L{Token} @type errors: C{list} of L{ParseError} @rtype: C{int} """ linenum = start + 1 doublecolon = 0 while linenum < len(lines): # Find the indentation of this line. line = lines[linenum] indent = len(line) - len(line.lstrip()) # "::" markers end paragraphs. if doublecolon: break if line.rstrip()[-2:] == '::': doublecolon = 1 # Blank lines end paragraphs if indent == len(line): break # Indentation changes end paragraphs if indent != para_indent: break # List bullets end paragraphs if _BULLET_RE.match(line, indent): break # Check for mal-formatted field items. if line[indent] == '@': estr = "Possible mal-formatted field item." errors.append(TokenizationError(estr, linenum, is_fatal=0)) # Go on to the next line. linenum += 1 contents = [line.strip() for line in lines[start:linenum]] # Does this token look like a heading? if ((len(contents) < 2) or (contents[1][0] not in _HEADING_CHARS) or (abs(len(contents[0])-len(contents[1])) > 5)): looks_like_heading = 0 else: looks_like_heading = 1 for char in contents[1]: if char != contents[1][0]: looks_like_heading = 0 break if looks_like_heading: if len(contents[0]) != len(contents[1]): estr = ("Possible heading typo: the number of "+ "underline characters must match the "+ "number of heading characters.") errors.append(TokenizationError(estr, start, is_fatal=0)) else: level = _HEADING_CHARS.index(contents[1][0]) tokens.append(Token(Token.HEADING, start, contents[0], para_indent, level)) return start+2 # Add the paragraph token, and return the linenum after it ends. contents = ' '.join(contents) tokens.append(Token(Token.PARA, start, contents, para_indent)) return linenum def _tokenize(str, errors): """ Split a given formatted docstring into an ordered list of C{Token}s, according to the epytext markup rules. @param str: The epytext string @type str: C{string} @param errors: A list where any errors generated during parsing will be stored. If no list is specified, then errors will generate exceptions. @type errors: C{list} of L{ParseError} @return: a list of the C{Token}s that make up the given string. @rtype: C{list} of L{Token} """ tokens = [] lines = str.split('\n') # Scan through the lines, determining what @type of token we're # dealing with, and tokenizing it, as appropriate. linenum = 0 while linenum < len(lines): # Get the current line and its indentation. line = lines[linenum] indent = len(line)-len(line.lstrip()) if indent == len(line): # Ignore blank lines. linenum += 1 continue elif line[indent:indent+4] == '>>> ': # blocks starting with ">>> " are doctest block tokens. linenum = _tokenize_doctest(lines, linenum, indent, tokens, errors) elif _BULLET_RE.match(line, indent): # blocks starting with a bullet are LI start tokens. linenum = _tokenize_listart(lines, linenum, indent, tokens, errors) if tokens[-1].indent != None: indent = tokens[-1].indent else: # Check for mal-formatted field items. if line[indent] == '@': estr = "Possible mal-formatted field item." errors.append(TokenizationError(estr, linenum, is_fatal=0)) # anything else is either a paragraph or a heading. linenum = _tokenize_para(lines, linenum, indent, tokens, errors) # Paragraph tokens ending in '::' initiate literal blocks. if (tokens[-1].tag == Token.PARA and tokens[-1].contents[-2:] == '::'): tokens[-1].contents = tokens[-1].contents[:-1] linenum = _tokenize_literal(lines, linenum, indent, tokens, errors) return tokens ################################################## ## Inline markup ("colorizing") ################################################## # Assorted regular expressions used for colorizing. _BRACE_RE = re.compile('{|}') _TARGET_RE = re.compile('^(.*?)\s*<(?:URI:|URL:)?([^<>]+)>$') def _colorize(doc, token, errors, tagName='para'): """ Given a string containing the contents of a paragraph, produce a DOM C{Element} encoding that paragraph. Colorized regions are represented using DOM C{Element}s, and text is represented using DOM C{Text}s. @param errors: A list of errors. Any newly generated errors will be appended to this list. @type errors: C{list} of C{string} @param tagName: The element tag for the DOM C{Element} that should be generated. @type tagName: C{string} @return: a DOM C{Element} encoding the given paragraph. @returntype: C{Element} """ str = token.contents linenum = 0 # Maintain a stack of DOM elements, containing the ancestors of # the text currently being analyzed. New elements are pushed when # "{" is encountered, and old elements are popped when "}" is # encountered. stack = [Element(tagName)] # This is just used to make error-reporting friendlier. It's a # stack parallel to "stack" containing the index of each element's # open brace. openbrace_stack = [0] # Process the string, scanning for '{' and '}'s. start is the # index of the first unprocessed character. Each time through the # loop, we process the text from the first unprocessed character # to the next open or close brace. start = 0 while 1: match = _BRACE_RE.search(str, start) if match == None: break end = match.start() # Open braces start new colorizing elements. When preceeded # by a capital letter, they specify a colored region, as # defined by the _COLORIZING_TAGS dictionary. Otherwise, # use a special "literal braces" element (with tag "litbrace"), # and convert them to literal braces once we find the matching # close-brace. if match.group() == '{': if (end>0) and 'A' <= str[end-1] <= 'Z': if (end-1) > start: stack[-1].children.append(str[start:end-1]) if str[end-1] not in _COLORIZING_TAGS: estr = "Unknown inline markup tag." errors.append(ColorizingError(estr, token, end-1)) stack.append(Element('unknown')) else: tag = _COLORIZING_TAGS[str[end-1]] stack.append(Element(tag)) else: if end > start: stack[-1].children.append(str[start:end]) stack.append(Element('litbrace')) openbrace_stack.append(end) stack[-2].children.append(stack[-1]) # Close braces end colorizing elements. elif match.group() == '}': # Check for (and ignore) unbalanced braces. if len(stack) <= 1: estr = "Unbalanced '}'." errors.append(ColorizingError(estr, token, end)) start = end + 1 continue # Add any remaining text. if end > start: stack[-1].children.append(str[start:end]) # Special handling for symbols: if stack[-1].tag == 'symbol': if (len(stack[-1].children) != 1 or not isinstance(stack[-1].children[0], basestring)): estr = "Invalid symbol code." errors.append(ColorizingError(estr, token, end)) else: symb = stack[-1].children[0] if symb in _SYMBOLS: # It's a symbol stack[-2].children[-1] = Element('symbol', symb) else: estr = "Invalid symbol code." errors.append(ColorizingError(estr, token, end)) # Special handling for escape elements: if stack[-1].tag == 'escape': if (len(stack[-1].children) != 1 or not isinstance(stack[-1].children[0], basestring)): estr = "Invalid escape code." errors.append(ColorizingError(estr, token, end)) else: escp = stack[-1].children[0] if escp in _ESCAPES: # It's an escape from _ESCPAES stack[-2].children[-1] = _ESCAPES[escp] elif len(escp) == 1: # It's a single-character escape (eg E{.}) stack[-2].children[-1] = escp else: estr = "Invalid escape code." errors.append(ColorizingError(estr, token, end)) # Special handling for literal braces elements: if stack[-1].tag == 'litbrace': stack[-2].children[-1:] = ['{'] + stack[-1].children + ['}'] # Special handling for graphs: if stack[-1].tag == 'graph': _colorize_graph(doc, stack[-1], token, end, errors) # Special handling for link-type elements: if stack[-1].tag in _LINK_COLORIZING_TAGS: _colorize_link(doc, stack[-1], token, end, errors) # Pop the completed element. openbrace_stack.pop() stack.pop() start = end+1 # Add any final text. if start < len(str): stack[-1].children.append(str[start:]) if len(stack) != 1: estr = "Unbalanced '{'." errors.append(ColorizingError(estr, token, openbrace_stack[-1])) return stack[0] GRAPH_TYPES = ['classtree', 'packagetree', 'importgraph', 'callgraph'] def _colorize_graph(doc, graph, token, end, errors): """ Eg:: G{classtree} G{classtree x, y, z} G{importgraph} """ bad_graph_spec = False children = graph.children[:] graph.children = [] if len(children) != 1 or not isinstance(children[0], basestring): bad_graph_spec = "Bad graph specification" else: pieces = children[0].split(None, 1) graphtype = pieces[0].replace(':','').strip().lower() if graphtype in GRAPH_TYPES: if len(pieces) == 2: if re.match(r'\s*:?\s*([\w\.]+\s*,?\s*)*', pieces[1]): args = pieces[1].replace(',', ' ').replace(':','').split() else: bad_graph_spec = "Bad graph arg list" else: args = [] else: bad_graph_spec = ("Bad graph type %s -- use one of %s" % (pieces[0], ', '.join(GRAPH_TYPES))) if bad_graph_spec: errors.append(ColorizingError(bad_graph_spec, token, end)) graph.children.append('none') graph.children.append('') return graph.children.append(graphtype) for arg in args: graph.children.append(arg) def _colorize_link(doc, link, token, end, errors): variables = link.children[:] # If the last child isn't text, we know it's bad. if len(variables)==0 or not isinstance(variables[-1], basestring): estr = "Bad %s target." % link.tag errors.append(ColorizingError(estr, token, end)) return # Did they provide an explicit target? match2 = _TARGET_RE.match(variables[-1]) if match2: (text, target) = match2.groups() variables[-1] = text # Can we extract an implicit target? elif len(variables) == 1: target = variables[0] else: estr = "Bad %s target." % link.tag errors.append(ColorizingError(estr, token, end)) return # Construct the name element. name_elt = Element('name', *variables) # Clean up the target. For URIs, assume http or mailto if they # don't specify (no relative urls) target = re.sub(r'\s', '', target) if link.tag=='uri': if not re.match(r'\w+:', target): if re.match(r'\w+@(\w+)(\.\w+)*', target): target = 'mailto:' + target else: target = 'http://'+target elif link.tag=='link': # Remove arg lists for functions (e.g., L{_colorize_link()}) target = re.sub(r'\(.*\)$', '', target) if not re.match(r'^[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*$', target): estr = "Bad link target." errors.append(ColorizingError(estr, token, end)) return # Construct the target element. target_elt = Element('target', target) # Add them to the link element. link.children = [name_elt, target_elt] ################################################## ## Formatters ################################################## def to_epytext(tree, indent=0, seclevel=0): """ Convert a DOM document encoding epytext back to an epytext string. This is the inverse operation from L{parse}. I.e., assuming there are no errors, the following is true: - C{parse(to_epytext(tree)) == tree} The inverse is true, except that whitespace, line wrapping, and character escaping may be done differently. - C{to_epytext(parse(str)) == str} (approximately) @param tree: A DOM document encoding of an epytext string. @type tree: C{Element} @param indent: The indentation for the string representation of C{tree}. Each line of the returned string will begin with C{indent} space characters. @type indent: C{int} @param seclevel: The section level that C{tree} appears at. This is used to generate section headings. @type seclevel: C{int} @return: The epytext string corresponding to C{tree}. @rtype: C{string} """ if isinstance(tree, basestring): str = re.sub(r'\{', '\0', tree) str = re.sub(r'\}', '\1', str) return str if tree.tag == 'epytext': indent -= 2 if tree.tag == 'section': seclevel += 1 variables = [to_epytext(c, indent+2, seclevel) for c in tree.children] childstr = ''.join(variables) # Clean up for literal blocks (add the double "::" back) childstr = re.sub(':(\s*)\2', '::\\1', childstr) if tree.tag == 'para': str = wordwrap(childstr, indent)+'\n' str = re.sub(r'((^|\n)\s*\d+)\.', r'\1E{.}', str) str = re.sub(r'((^|\n)\s*)-', r'\1E{-}', str) str = re.sub(r'((^|\n)\s*)@', r'\1E{@}', str) str = re.sub(r'::(\s*($|\n))', r'E{:}E{:}\1', str) str = re.sub('\0', 'E{lb}', str) str = re.sub('\1', 'E{rb}', str) return str elif tree.tag == 'li': bullet = tree.attribs.get('bullet') or '-' return indent*' '+ bullet + ' ' + childstr.lstrip() elif tree.tag == 'heading': str = re.sub('\0', 'E{lb}',childstr) str = re.sub('\1', 'E{rb}', str) uline = len(childstr)*_HEADING_CHARS[seclevel-1] return (indent-2)*' ' + str + '\n' + (indent-2)*' '+uline+'\n' elif tree.tag == 'doctestblock': str = re.sub('\0', '{', childstr) str = re.sub('\1', '}', str) lines = [' '+indent*' '+line for line in str.split('\n')] return '\n'.join(lines) + '\n\n' elif tree.tag == 'literalblock': str = re.sub('\0', '{', childstr) str = re.sub('\1', '}', str) lines = [(indent+1)*' '+line for line in str.split('\n')] return '\2' + '\n'.join(lines) + '\n\n' elif tree.tag == 'field': numargs = 0 while tree.children[numargs+1].tag == 'arg': numargs += 1 tag = variables[0] args = variables[1:1+numargs] body = variables[1+numargs:] str = (indent)*' '+'@'+variables[0] if args: str += '(' + ', '.join(args) + ')' return str + ':\n' + ''.join(body) elif tree.tag == 'target': return '<%s>' % childstr elif tree.tag in ('fieldlist', 'tag', 'arg', 'epytext', 'section', 'olist', 'ulist', 'name'): return childstr elif tree.tag == 'symbol': return 'E{%s}' % childstr elif tree.tag == 'graph': return 'G{%s}' % ' '.join(variables) else: for (tag, name) in _COLORIZING_TAGS.items(): if name == tree.tag: return '%s{%s}' % (tag, childstr) raise ValueError('Unknown DOM element %r' % tree.tag) SYMBOL_TO_PLAINTEXT = { 'crarr': '\\', } def to_plaintext(tree, indent=0, seclevel=0): """ Convert a DOM document encoding epytext to a string representation. This representation is similar to the string generated by C{to_epytext}, but C{to_plaintext} removes inline markup, prints escaped characters in unescaped form, etc. @param tree: A DOM document encoding of an epytext string. @type tree: C{Element} @param indent: The indentation for the string representation of C{tree}. Each line of the returned string will begin with C{indent} space characters. @type indent: C{int} @param seclevel: The section level that C{tree} appears at. This is used to generate section headings. @type seclevel: C{int} @return: The epytext string corresponding to C{tree}. @rtype: C{string} """ if isinstance(tree, basestring): return tree if tree.tag == 'section': seclevel += 1 # Figure out the child indent level. if tree.tag == 'epytext': cindent = indent elif tree.tag == 'li' and tree.attribs.get('bullet'): cindent = indent + 1 + len(tree.attribs.get('bullet')) else: cindent = indent + 2 variables = [to_plaintext(c, cindent, seclevel) for c in tree.children] childstr = ''.join(variables) if tree.tag == 'para': return wordwrap(childstr, indent)+'\n' elif tree.tag == 'li': # We should be able to use getAttribute here; but there's no # convenient way to test if an element has an attribute.. bullet = tree.attribs.get('bullet') or '-' return indent*' ' + bullet + ' ' + childstr.lstrip() elif tree.tag == 'heading': uline = len(childstr)*_HEADING_CHARS[seclevel-1] return ((indent-2)*' ' + childstr + '\n' + (indent-2)*' ' + uline + '\n') elif tree.tag == 'doctestblock': lines = [(indent+2)*' '+line for line in childstr.split('\n')] return '\n'.join(lines) + '\n\n' elif tree.tag == 'literalblock': lines = [(indent+1)*' '+line for line in childstr.split('\n')] return '\n'.join(lines) + '\n\n' elif tree.tag == 'fieldlist': return childstr elif tree.tag == 'field': numargs = 0 while tree.children[numargs+1].tag == 'arg': numargs += 1 tag = variables[0] args = variables[1:1+numargs] body = variables[1+numargs:] str = (indent)*' '+'@'+variables[0] if args: str += '(' + ', '.join(args) + ')' return str + ':\n' + ''.join(body) elif tree.tag == 'uri': if len(variables) != 2: raise ValueError('Bad URI ') elif variables[0] == variables[1]: return '<%s>' % variables[1] else: return '%r<%s>' % (variables[0], variables[1]) elif tree.tag == 'link': if len(variables) != 2: raise ValueError('Bad Link') return '%s' % variables[0] elif tree.tag in ('olist', 'ulist'): # [xx] always use condensed lists. ## Use a condensed list if each list item is 1 line long. #for child in variables: # if child.count('\n') > 2: return childstr return childstr.replace('\n\n', '\n')+'\n' elif tree.tag == 'symbol': return '%s' % SYMBOL_TO_PLAINTEXT.get(childstr, childstr) elif tree.tag == 'graph': return '<<%s graph: %s>>' % (variables[0], ', '.join(variables[1:])) else: # Assume that anything else can be passed through. return childstr def to_debug(tree, indent=4, seclevel=0): """ Convert a DOM document encoding epytext back to an epytext string, annotated with extra debugging information. This function is similar to L{to_epytext}, but it adds explicit information about where different blocks begin, along the left margin. @param tree: A DOM document encoding of an epytext string. @type tree: C{Element} @param indent: The indentation for the string representation of C{tree}. Each line of the returned string will begin with C{indent} space characters. @type indent: C{int} @param seclevel: The section level that C{tree} appears at. This is used to generate section headings. @type seclevel: C{int} @return: The epytext string corresponding to C{tree}. @rtype: C{string} """ if isinstance(tree, basestring): str = re.sub(r'\{', '\0', tree) str = re.sub(r'\}', '\1', str) return str if tree.tag == 'section': seclevel += 1 variables = [to_debug(c, indent+2, seclevel) for c in tree.children] childstr = ''.join(variables) # Clean up for literal blocks (add the double "::" back) childstr = re.sub(':( *\n \|\n)\2', '::\\1', childstr) if tree.tag == 'para': str = wordwrap(childstr, indent-6, 69)+'\n' str = re.sub(r'((^|\n)\s*\d+)\.', r'\1E{.}', str) str = re.sub(r'((^|\n)\s*)-', r'\1E{-}', str) str = re.sub(r'((^|\n)\s*)@', r'\1E{@}', str) str = re.sub(r'::(\s*($|\n))', r'E{:}E{:}\1', str) str = re.sub('\0', 'E{lb}', str) str = re.sub('\1', 'E{rb}', str) lines = str.rstrip().split('\n') lines[0] = ' P>|' + lines[0] lines[1:] = [' |'+l for l in lines[1:]] return '\n'.join(lines)+'\n |\n' elif tree.tag == 'li': bullet = tree.attribs.get('bullet') or '-' return ' LI>|'+ (indent-6)*' '+ bullet + ' ' + childstr[6:].lstrip() elif tree.tag in ('olist', 'ulist'): return 'LIST>|'+(indent-4)*' '+childstr[indent+2:] elif tree.tag == 'heading': str = re.sub('\0', 'E{lb}', childstr) str = re.sub('\1', 'E{rb}', str) uline = len(childstr)*_HEADING_CHARS[seclevel-1] return ('SEC'+`seclevel`+'>|'+(indent-8)*' ' + str + '\n' + ' |'+(indent-8)*' ' + uline + '\n') elif tree.tag == 'doctestblock': str = re.sub('\0', '{', childstr) str = re.sub('\1', '}', str) lines = [' |'+(indent-4)*' '+line for line in str.split('\n')] lines[0] = 'DTST>'+lines[0][5:] return '\n'.join(lines) + '\n |\n' elif tree.tag == 'literalblock': str = re.sub('\0', '{', childstr) str = re.sub('\1', '}', str) lines = [' |'+(indent-5)*' '+line for line in str.split('\n')] lines[0] = ' LIT>'+lines[0][5:] return '\2' + '\n'.join(lines) + '\n |\n' elif tree.tag == 'field': numargs = 0 while tree.children[numargs+1].tag == 'arg': numargs += 1 tag = variables[0] args = variables[1:1+numargs] body = variables[1+numargs:] str = ' FLD>|'+(indent-6)*' '+'@'+variables[0] if args: str += '(' + ', '.join(args) + ')' return str + ':\n' + ''.join(body) elif tree.tag == 'target': return '<%s>' % childstr elif tree.tag in ('fieldlist', 'tag', 'arg', 'epytext', 'section', 'olist', 'ulist', 'name'): return childstr elif tree.tag == 'symbol': return 'E{%s}' % childstr elif tree.tag == 'graph': return 'G{%s}' % ' '.join(variables) else: for (tag, name) in _COLORIZING_TAGS.items(): if name == tree.tag: return '%s{%s}' % (tag, childstr) raise ValueError('Unknown DOM element %r' % tree.tag) ################################################## ## Top-Level Wrapper function ################################################## def pparse(str, show_warnings=1, show_errors=1, stream=sys.stderr): """ Pretty-parse the string. This parses the string, and catches any warnings or errors produced. Any warnings and errors are displayed, and the resulting DOM parse structure is returned. @param str: The string to parse. @type str: C{string} @param show_warnings: Whether or not to display non-fatal errors generated by parsing C{str}. @type show_warnings: C{boolean} @param show_errors: Whether or not to display fatal errors generated by parsing C{str}. @type show_errors: C{boolean} @param stream: The stream that warnings and errors should be written to. @type stream: C{stream} @return: a DOM document encoding the contents of C{str}. @rtype: C{Element} @raise SyntaxError: If any fatal errors were encountered. """ errors = [] confused = 0 try: val = parse(str, errors) warnings = [e for e in errors if not e.is_fatal()] errors = [e for e in errors if e.is_fatal()] except: confused = 1 if not show_warnings: warnings = [] warnings.sort() errors.sort() if warnings: print >>stream, '='*SCRWIDTH print >>stream, "WARNINGS" print >>stream, '-'*SCRWIDTH for warning in warnings: print >>stream, warning.as_warning() print >>stream, '='*SCRWIDTH if errors and show_errors: if not warnings: print >>stream, '='*SCRWIDTH print >>stream, "ERRORS" print >>stream, '-'*SCRWIDTH for error in errors: print >>stream, error print >>stream, '='*SCRWIDTH if confused: raise elif errors: raise SyntaxError('Encountered Errors') else: return val ################################################## ## Parse Errors ################################################## class TokenizationError(ParseError): """ An error generated while tokenizing a formatted documentation string. """ class StructuringError(ParseError): """ An error generated while structuring a formatted documentation string. """ class ColorizingError(ParseError): """ An error generated while colorizing a paragraph. """ def __init__(self, descr, token, charnum, is_fatal=1): """ Construct a new colorizing exception. @param descr: A short description of the error. @type descr: C{string} @param token: The token where the error occured @type token: L{Token} @param charnum: The character index of the position in C{token} where the error occured. @type charnum: C{int} """ ParseError.__init__(self, descr, token.startline, is_fatal) self.token = token self.charnum = charnum CONTEXT_RANGE = 20 def descr(self): RANGE = self.CONTEXT_RANGE if self.charnum <= RANGE: left = self.token.contents[0:self.charnum] else: left = '...'+self.token.contents[self.charnum-RANGE:self.charnum] if (len(self.token.contents)-self.charnum) <= RANGE: right = self.token.contents[self.charnum:] else: right = (self.token.contents[self.charnum:self.charnum+RANGE] + '...') return ('%s\n\n%s%s\n%s^' % (self._descr, left, right, ' '*len(left))) ################################################## ## Convenience parsers ################################################## def parse_as_literal(str): """ Return a DOM document matching the epytext DTD, containing a single literal block. That literal block will include the contents of the given string. This method is typically used as a fall-back when the parser fails. @param str: The string which should be enclosed in a literal block. @type str: C{string} @return: A DOM document containing C{str} in a single literal block. @rtype: C{Element} """ return Element('epytext', Element('literalblock', str)) def parse_as_para(str): """ Return a DOM document matching the epytext DTD, containing a single paragraph. That paragraph will include the contents of the given string. This can be used to wrap some forms of automatically generated information (such as type names) in paragraphs. @param str: The string which should be enclosed in a paragraph. @type str: C{string} @return: A DOM document containing C{str} in a single paragraph. @rtype: C{Element} """ return Element('epytext', Element('para', str)) ################################################################# ## SUPPORT FOR EPYDOC ################################################################# def parse_docstring(docstring, errors, **options): """ Parse the given docstring, which is formatted using epytext; and return a C{ParsedDocstring} representation of its contents. @param docstring: The docstring to parse @type docstring: C{string} @param errors: A list where any errors generated during parsing will be stored. @type errors: C{list} of L{ParseError} @param options: Extra options. Unknown options are ignored. Currently, no extra options are defined. @rtype: L{ParsedDocstring} """ return ParsedEpytextDocstring(parse(docstring, errors), **options) class ParsedEpytextDocstring(ParsedDocstring): SYMBOL_TO_HTML = { # Symbols '<-': '←', '->': '→', '^': '↑', 'v': '↓', # Greek letters 'alpha': 'α', 'beta': 'β', 'gamma': 'γ', 'delta': 'δ', 'epsilon': 'ε', 'zeta': 'ζ', 'eta': 'η', 'theta': 'θ', 'iota': 'ι', 'kappa': 'κ', 'lambda': 'λ', 'mu': 'μ', 'nu': 'ν', 'xi': 'ξ', 'omicron': 'ο', 'pi': 'π', 'rho': 'ρ', 'sigma': 'σ', 'tau': 'τ', 'upsilon': 'υ', 'phi': 'φ', 'chi': 'χ', 'psi': 'ψ', 'omega': 'ω', 'Alpha': 'Α', 'Beta': 'Β', 'Gamma': 'Γ', 'Delta': 'Δ', 'Epsilon': 'Ε', 'Zeta': 'Ζ', 'Eta': 'Η', 'Theta': 'Θ', 'Iota': 'Ι', 'Kappa': 'Κ', 'Lambda': 'Λ', 'Mu': 'Μ', 'Nu': 'Ν', 'Xi': 'Ξ', 'Omicron': 'Ο', 'Pi': 'Π', 'Rho': 'Ρ', 'Sigma': 'Σ', 'Tau': 'Τ', 'Upsilon': 'Υ', 'Phi': 'Φ', 'Chi': 'Χ', 'Psi': 'Ψ', 'Omega': 'Ω', # HTML character entities 'larr': '←', 'rarr': '→', 'uarr': '↑', 'darr': '↓', 'harr': '↔', 'crarr': '↵', 'lArr': '⇐', 'rArr': '⇒', 'uArr': '⇑', 'dArr': '⇓', 'hArr': '⇔', 'copy': '©', 'times': '×', 'forall': '∀', 'exist': '∃', 'part': '∂', 'empty': '∅', 'isin': '∈', 'notin': '∉', 'ni': '∋', 'prod': '∏', 'sum': '∑', 'prop': '∝', 'infin': '∞', 'ang': '∠', 'and': '∧', 'or': '∨', 'cap': '∩', 'cup': '∪', 'int': '∫', 'there4': '∴', 'sim': '∼', 'cong': '≅', 'asymp': '≈', 'ne': '≠', 'equiv': '≡', 'le': '≤', 'ge': '≥', 'sub': '⊂', 'sup': '⊃', 'nsub': '⊄', 'sube': '⊆', 'supe': '⊇', 'oplus': '⊕', 'otimes': '⊗', 'perp': '⊥', # Alternate (long) names 'infinity': '∞', 'integral': '∫', 'product': '∏', '<=': '≤', '>=': '≥', } SYMBOL_TO_LATEX = { # Symbols '<-': r'\(\leftarrow\)', '->': r'\(\rightarrow\)', '^': r'\(\uparrow\)', 'v': r'\(\downarrow\)', # Greek letters (use lower case when upcase not available) 'alpha': r'\(\alpha\)', 'beta': r'\(\beta\)', 'gamma': r'\(\gamma\)', 'delta': r'\(\delta\)', 'epsilon': r'\(\epsilon\)', 'zeta': r'\(\zeta\)', 'eta': r'\(\eta\)', 'theta': r'\(\theta\)', 'iota': r'\(\iota\)', 'kappa': r'\(\kappa\)', 'lambda': r'\(\lambda\)', 'mu': r'\(\mu\)', 'nu': r'\(\nu\)', 'xi': r'\(\xi\)', 'omicron': r'\(o\)', 'pi': r'\(\pi\)', 'rho': r'\(\rho\)', 'sigma': r'\(\sigma\)', 'tau': r'\(\tau\)', 'upsilon': r'\(\upsilon\)', 'phi': r'\(\phi\)', 'chi': r'\(\chi\)', 'psi': r'\(\psi\)', 'omega': r'\(\omega\)', 'Alpha': r'\(\alpha\)', 'Beta': r'\(\beta\)', 'Gamma': r'\(\Gamma\)', 'Delta': r'\(\Delta\)', 'Epsilon': r'\(\epsilon\)', 'Zeta': r'\(\zeta\)', 'Eta': r'\(\eta\)', 'Theta': r'\(\Theta\)', 'Iota': r'\(\iota\)', 'Kappa': r'\(\kappa\)', 'Lambda': r'\(\Lambda\)', 'Mu': r'\(\mu\)', 'Nu': r'\(\nu\)', 'Xi': r'\(\Xi\)', 'Omicron': r'\(o\)', 'Pi': r'\(\Pi\)', 'ho': r'\(\rho\)', 'Sigma': r'\(\Sigma\)', 'Tau': r'\(\tau\)', 'Upsilon': r'\(\Upsilon\)', 'Phi': r'\(\Phi\)', 'Chi': r'\(\chi\)', 'Psi': r'\(\Psi\)', 'Omega': r'\(\Omega\)', # HTML character entities 'larr': r'\(\leftarrow\)', 'rarr': r'\(\rightarrow\)', 'uarr': r'\(\uparrow\)', 'darr': r'\(\downarrow\)', 'harr': r'\(\leftrightarrow\)', 'crarr': r'\(\hookleftarrow\)', 'lArr': r'\(\Leftarrow\)', 'rArr': r'\(\Rightarrow\)', 'uArr': r'\(\Uparrow\)', 'dArr': r'\(\Downarrow\)', 'hArr': r'\(\Leftrightarrow\)', 'copy': r'{\textcopyright}', 'times': r'\(\times\)', 'forall': r'\(\forall\)', 'exist': r'\(\exists\)', 'part': r'\(\partial\)', 'empty': r'\(\emptyset\)', 'isin': r'\(\in\)', 'notin': r'\(\notin\)', 'ni': r'\(\ni\)', 'prod': r'\(\prod\)', 'sum': r'\(\sum\)', 'prop': r'\(\propto\)', 'infin': r'\(\infty\)', 'ang': r'\(\angle\)', 'and': r'\(\wedge\)', 'or': r'\(\vee\)', 'cap': r'\(\cap\)', 'cup': r'\(\cup\)', 'int': r'\(\int\)', 'there4': r'\(\therefore\)', 'sim': r'\(\sim\)', 'cong': r'\(\cong\)', 'asymp': r'\(\approx\)', 'ne': r'\(\ne\)', 'equiv': r'\(\equiv\)', 'le': r'\(\le\)', 'ge': r'\(\ge\)', 'sub': r'\(\subset\)', 'sup': r'\(\supset\)', 'nsub': r'\(\supset\)', 'sube': r'\(\subseteq\)', 'supe': r'\(\supseteq\)', 'oplus': r'\(\oplus\)', 'otimes': r'\(\otimes\)', 'perp': r'\(\perp\)', # Alternate (long) names 'infinity': r'\(\infty\)', 'integral': r'\(\int\)', 'product': r'\(\prod\)', '<=': r'\(\le\)', '>=': r'\(\ge\)', } def __init__(self, dom_tree, **options): self._tree = dom_tree # Caching: self._html = self._latex = self._plaintext = None self._terms = None # inline option -- mark top-level children as inline. if options.get('inline') and self._tree is not None: for elt in self._tree.children: elt.attribs['inline'] = True def __str__(self): return str(self._tree) def to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options): if self._html is not None: return self._html if self._tree is None: return '' indent = options.get('indent', 0) self._html = self._to_html(self._tree, docstring_linker, directory, docindex, context, indent) return self._html def to_latex(self, docstring_linker, **options): if self._latex is not None: return self._latex if self._tree is None: return '' indent = options.get('indent', 0) self._hyperref = options.get('hyperref', 1) self._latex = self._to_latex(self._tree, docstring_linker, indent) return self._latex def to_plaintext(self, docstring_linker, **options): # [XX] don't cache -- different options might be used!! #if self._plaintext is not None: return self._plaintext if self._tree is None: return '' if 'indent' in options: self._plaintext = to_plaintext(self._tree, indent=options['indent']) else: self._plaintext = to_plaintext(self._tree) return self._plaintext def _index_term_key(self, tree): str = to_plaintext(tree) str = re.sub(r'\s\s+', '-', str) return "index-"+re.sub("[^a-zA-Z0-9]", "_", str) def _to_html(self, tree, linker, directory, docindex, context, indent=0, seclevel=0): if isinstance(tree, basestring): return plaintext_to_html(tree) if tree.tag == 'epytext': indent -= 2 if tree.tag == 'section': seclevel += 1 # Process the variables first. variables = [self._to_html(c, linker, directory, docindex, context, indent+2, seclevel) for c in tree.children] # Construct the HTML string for the variables. childstr = ''.join(variables) # Perform the approriate action for the DOM tree type. if tree.tag == 'para': return wordwrap( (tree.attribs.get('inline') and '%s' or '

      %s

      ') % childstr, indent) elif tree.tag == 'code': style = tree.attribs.get('style') if style: return '%s' % (style, childstr) else: return '%s' % childstr elif tree.tag == 'uri': return ('%s' % (variables[1], variables[0])) elif tree.tag == 'link': return linker.translate_identifier_xref(variables[1], variables[0]) elif tree.tag == 'italic': return '%s' % childstr elif tree.tag == 'math': return '%s' % childstr elif tree.tag == 'indexed': term = Element('epytext', *tree.children, **tree.attribs) return linker.translate_indexterm(ParsedEpytextDocstring(term)) #term_key = self._index_term_key(tree) #return linker.translate_indexterm(childstr, term_key) elif tree.tag == 'bold': return '%s' % childstr elif tree.tag == 'ulist': return '%s
        \n%s%s
      \n' % (indent*' ', childstr, indent*' ') elif tree.tag == 'olist': start = tree.attribs.get('start') or '' return ('%s
        \n%s%s
      \n' % (indent*' ', start, childstr, indent*' ')) elif tree.tag == 'li': return indent*' '+'
    • \n%s%s
    • \n' % (childstr, indent*' ') elif tree.tag == 'heading': return ('%s%s\n' % ((indent-2)*' ', seclevel, childstr, seclevel)) elif tree.tag == 'literalblock': return '
      \n%s\n
      \n' % childstr elif tree.tag == 'doctestblock': return doctest_to_html(tree.children[0].strip()) elif tree.tag == 'fieldlist': raise AssertionError("There should not be any field lists left") elif tree.tag in ('epytext', 'section', 'tag', 'arg', 'name', 'target', 'html'): return childstr elif tree.tag == 'symbol': symbol = tree.children[0] return self.SYMBOL_TO_HTML.get(symbol, '[%s]' % symbol) elif tree.tag == 'graph': # Generate the graph. graph = self._build_graph(variables[0], variables[1:], linker, docindex, context) if not graph: return '' # Write the graph. image_url = '%s.gif' % graph.uid image_file = os.path.join(directory, image_url) return graph.to_html(image_file, image_url) else: raise ValueError('Unknown epytext DOM element %r' % tree.tag) #GRAPH_TYPES = ['classtree', 'packagetree', 'importgraph'] def _build_graph(self, graph_type, graph_args, linker, docindex, context): # Generate the graph if graph_type == 'classtree': from epydoc.apidoc import ClassDoc if graph_args: bases = [docindex.find(name, context) for name in graph_args] elif isinstance(context, ClassDoc): bases = [context] else: log.warning("Could not construct class tree: you must " "specify one or more base classes.") return None from epydoc.docwriter.dotgraph import class_tree_graph return class_tree_graph(bases, linker, context) elif graph_type == 'packagetree': from epydoc.apidoc import ModuleDoc if graph_args: packages = [docindex.find(name, context) for name in graph_args] elif isinstance(context, ModuleDoc): packages = [context] else: log.warning("Could not construct package tree: you must " "specify one or more root packages.") return None from epydoc.docwriter.dotgraph import package_tree_graph return package_tree_graph(packages, linker, context) elif graph_type == 'importgraph': from epydoc.apidoc import ModuleDoc modules = [d for d in docindex.root if isinstance(d, ModuleDoc)] from epydoc.docwriter.dotgraph import import_graph return import_graph(modules, docindex, linker, context) elif graph_type == 'callgraph': if graph_args: docs = [docindex.find(name, context) for name in graph_args] docs = [doc for doc in docs if doc is not None] else: docs = [context] from epydoc.docwriter.dotgraph import call_graph return call_graph(docs, docindex, linker, context) else: log.warning("Unknown graph type %s" % graph_type) def _to_latex(self, tree, linker, indent=0, seclevel=0, breakany=0): if isinstance(tree, basestring): return plaintext_to_latex(tree, breakany=breakany) if tree.tag == 'section': seclevel += 1 # Figure out the child indent level. if tree.tag == 'epytext': cindent = indent else: cindent = indent + 2 variables = [self._to_latex(c, linker, cindent, seclevel, breakany) for c in tree.children] childstr = ''.join(variables) if tree.tag == 'para': return wordwrap(childstr, indent)+'\n' elif tree.tag == 'code': return '\\texttt{%s}' % childstr elif tree.tag == 'uri': if len(variables) != 2: raise ValueError('Bad URI ') if self._hyperref: # ~ and # should not be escaped in the URI. uri = tree.children[1].children[0] uri = uri.replace('{\\textasciitilde}', '~') uri = uri.replace('\\#', '#') if variables[0] == variables[1]: return '\\href{%s}{\\textit{%s}}' % (uri, variables[1]) else: return ('%s\\footnote{\\href{%s}{%s}}' % (variables[0], uri, variables[1])) else: if variables[0] == variables[1]: return '\\textit{%s}' % variables[1] else: return '%s\\footnote{%s}' % (variables[0], variables[1]) elif tree.tag == 'link': if len(variables) != 2: raise ValueError('Bad Link') return linker.translate_identifier_xref(variables[1], variables[0]) elif tree.tag == 'italic': return '\\textit{%s}' % childstr elif tree.tag == 'math': return '\\textit{%s}' % childstr elif tree.tag == 'indexed': term = Element('epytext', *tree.children, **tree.attribs) return linker.translate_indexterm(ParsedEpytextDocstring(term)) elif tree.tag == 'bold': return '\\textbf{%s}' % childstr elif tree.tag == 'li': return indent*' ' + '\\item ' + childstr.lstrip() elif tree.tag == 'heading': return ' '*(indent-2) + '(section) %s\n\n' % childstr elif tree.tag == 'doctestblock': return doctest_to_latex(tree.children[0].strip()) elif tree.tag == 'literalblock': return '\\begin{alltt}\n%s\\end{alltt}\n\n' % childstr elif tree.tag == 'fieldlist': return indent*' '+'{omitted fieldlist}\n' elif tree.tag == 'olist': return (' '*indent + '\\begin{enumerate}\n\n' + ' '*indent + '\\setlength{\\parskip}{0.5ex}\n' + childstr + ' '*indent + '\\end{enumerate}\n\n') elif tree.tag == 'ulist': return (' '*indent + '\\begin{itemize}\n' + ' '*indent + '\\setlength{\\parskip}{0.6ex}\n' + childstr + ' '*indent + '\\end{itemize}\n\n') elif tree.tag == 'symbol': symbol = tree.children[0] return self.SYMBOL_TO_LATEX.get(symbol, '[%s]' % symbol) elif tree.tag == 'graph': return '(GRAPH)' #raise ValueError, 'graph not implemented yet for latex' else: # Assume that anything else can be passed through. return childstr _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)') def summary(self): if self._tree is None: return self, False tree = self._tree doc = Element('epytext') # Find the first paragraph. variables = tree.children while (len(variables) > 0) and (variables[0].tag != 'para'): if variables[0].tag in ('section', 'ulist', 'olist', 'li'): variables = variables[0].children else: variables = variables[1:] # Special case: if the docstring contains a single literal block, # then try extracting the summary from it. if (len(variables) == 0 and len(tree.children) == 1 and tree.children[0].tag == 'literalblock'): str = re.split(r'\n\s*(\n|$).*', tree.children[0].children[0], 1)[0] variables = [Element('para')] variables[0].children.append(str) # If we didn't find a paragraph, return an empty epytext. if len(variables) == 0: return ParsedEpytextDocstring(doc), False # Is there anything else, excluding tags, after the first variable? long_docs = False for var in variables[1:]: if isinstance(var, Element) and var.tag == 'fieldlist': continue long_docs = True break # Extract the first sentence. parachildren = variables[0].children para = Element('para', inline=True) doc.children.append(para) for parachild in parachildren: if isinstance(parachild, basestring): m = self._SUMMARY_RE.match(parachild) if m: para.children.append(m.group(1)) long_docs |= parachild is not parachildren[-1] if not long_docs: other = parachild[m.end():] if other and not other.isspace(): long_docs = True return ParsedEpytextDocstring(doc), long_docs para.children.append(parachild) return ParsedEpytextDocstring(doc), long_docs def split_fields(self, errors=None): if self._tree is None: return (self, ()) tree = Element(self._tree.tag, *self._tree.children, **self._tree.attribs) fields = [] if (tree.children and tree.children[-1].tag == 'fieldlist' and tree.children[-1].children): field_nodes = tree.children[-1].children del tree.children[-1] for field in field_nodes: # Get the tag tag = field.children[0].children[0].lower() del field.children[0] # Get the argument. if field.children and field.children[0].tag == 'arg': arg = field.children[0].children[0] del field.children[0] else: arg = None # Process the field. field.tag = 'epytext' fields.append(Field(tag, arg, ParsedEpytextDocstring(field))) # Save the remaining docstring as the description.. if tree.children and tree.children[0].children: return ParsedEpytextDocstring(tree), fields else: return None, fields def index_terms(self): if self._terms is None: self._terms = [] self._index_terms(self._tree, self._terms) return self._terms def _index_terms(self, tree, terms): if tree is None or isinstance(tree, basestring): return if tree.tag == 'indexed': term = Element('epytext', *tree.children, **tree.attribs) terms.append(ParsedEpytextDocstring(term)) # Look for index items in child nodes. for child in tree.children: self._index_terms(child, terms) epydoc-3.0.1+dfsg/epydoc/markup/javadoc.py0000644000175000017500000002345710654406437020764 0ustar pronovicpronovic# # javadoc.py: javadoc docstring parsing # Edward Loper # # Created [07/03/03 12:37 PM] # $Id: javadoc.py 1574 2007-03-07 02:55:14Z dvarrazzo $ # """ Epydoc parser for U{Javadoc} docstrings. Javadoc is an HTML-based markup language that was developed for documenting Java APIs with inline comments. It consists of raw HTML, augmented by Javadoc tags. There are two types of Javadoc tag: - X{Javadoc block tags} correspond to Epydoc fields. They are marked by starting a line with a string of the form \"C{@M{tag} [M{arg}]}\", where C{M{tag}} indicates the type of block, and C{M{arg}} is an optional argument. (For fields that take arguments, Javadoc assumes that the single word immediately following the tag is an argument; multi-word arguments cannot be used with javadoc.) - X{inline Javadoc tags} are used for inline markup. In particular, epydoc uses them for crossreference links between documentation. Inline tags may appear anywhere in the text, and have the form \"C{{@M{tag} M{[args...]}}}\", where C{M{tag}} indicates the type of inline markup, and C{M{args}} are optional arguments. Epydoc supports all Javadoc tags, I{except}: - C{{@docRoot}}, which gives the (relative) URL of the generated documentation's root. - C{{@inheritDoc}}, which copies the documentation of the nearest overridden object. This can be used to combine the documentation of the overridden object with the documentation of the overridding object. - C{@serial}, C{@serialField}, and C{@serialData} which describe the serialization (pickling) of an object. - C{{@value}}, which copies the value of a constant. @warning: Epydoc only supports HTML output for Javadoc docstrings. """ __docformat__ = 'epytext en' # Imports import re from xml.dom.minidom import * from epydoc.markup import * def parse_docstring(docstring, errors, **options): """ Parse the given docstring, which is formatted using Javadoc; and return a C{ParsedDocstring} representation of its contents. @param docstring: The docstring to parse @type docstring: C{string} @param errors: A list where any errors generated during parsing will be stored. @type errors: C{list} of L{ParseError} @param options: Extra options. Unknown options are ignored. Currently, no extra options are defined. @rtype: L{ParsedDocstring} """ return ParsedJavadocDocstring(docstring, errors) class ParsedJavadocDocstring(ParsedDocstring): """ An encoded version of a Javadoc docstring. Since Javadoc is a fairly simple markup language, we don't do any processing in advance; instead, we wait to split fields or resolve crossreference links until we need to. @group Field Splitting: split_fields, _ARG_FIELDS, _FIELD_RE @cvar _ARG_FIELDS: A list of the fields that take arguments. Since Javadoc doesn't mark arguments in any special way, we must consult this list to decide whether the first word of a field is an argument or not. @cvar _FIELD_RE: A regular expression used to search for Javadoc block tags. @group HTML Output: to_html, _LINK_SPLIT_RE, _LINK_RE @cvar _LINK_SPLIT_RE: A regular expression used to search for Javadoc inline tags. @cvar _LINK_RE: A regular expression used to process Javadoc inline tags. """ def __init__(self, docstring, errors=None): """ Create a new C{ParsedJavadocDocstring}. @param docstring: The docstring that should be used to construct this C{ParsedJavadocDocstring}. @type docstring: C{string} @param errors: A list where any errors generated during parsing will be stored. If no list is given, then all errors are ignored. @type errors: C{list} of L{ParseError} """ self._docstring = docstring if errors is None: errors = [] self._check_links(errors) #//////////////////////////////////////////////////////////// # Field Splitting #//////////////////////////////////////////////////////////// _ARG_FIELDS = ('group variable var type cvariable cvar ivariable '+ 'ivar param '+ 'parameter arg argument raise raises exception '+ 'except deffield newfield keyword kwarg kwparam').split() _FIELD_RE = re.compile(r'(^\s*\@\w+[\s$])', re.MULTILINE) # Inherit docs from ParsedDocstring. def split_fields(self, errors=None): # Split the docstring into an alternating list of field tags # and text (odd pieces are field tags). pieces = self._FIELD_RE.split(self._docstring) # The first piece is the description. descr = ParsedJavadocDocstring(pieces[0]) # The remaining pieces are the block fields (alternating tags # and bodies; odd pieces are tags). fields = [] for i in range(1, len(pieces)): if i%2 == 1: # Get the field tag. tag = pieces[i].strip()[1:] else: # Get the field argument (if appropriate). if tag in self._ARG_FIELDS: subpieces = pieces[i].strip().split(None, 1)+['',''] (arg, body) = subpieces[:2] else: (arg, body) = (None, pieces[i]) # Special processing for @see fields, since Epydoc # allows unrestricted text in them, but Javadoc just # uses them for xref links: if tag == 'see' and body: if body[0] in '"\'': if body[-1] == body[0]: body = body[1:-1] elif body[0] == '<': pass else: body = '{@link %s}' % body # Construct the field. parsed_body = ParsedJavadocDocstring(body) fields.append(Field(tag, arg, parsed_body)) if pieces[0].strip(): return (descr, fields) else: return (None, fields) #//////////////////////////////////////////////////////////// # HTML Output. #//////////////////////////////////////////////////////////// _LINK_SPLIT_RE = re.compile(r'({@link(?:plain)?\s[^}]+})') _LINK_RE = re.compile(r'{@link(?:plain)?\s+' + r'([\w#.]+)' + r'(?:\([^\)]*\))?' + r'(\s+.*)?' + r'}') # Inherit docs from ParsedDocstring. def to_html(self, docstring_linker, **options): # Split the docstring into an alternating list of HTML and # links (odd pieces are links). pieces = self._LINK_SPLIT_RE.split(self._docstring) # This function is used to translate {@link ...}s to HTML. translate_xref = docstring_linker.translate_identifier_xref # Build up the HTML string from the pieces. For HTML pieces # (even), just add it to html. For link pieces (odd), use # docstring_linker to translate the crossreference link to # HTML for us. html = '' for i in range(len(pieces)): if i%2 == 0: html += pieces[i] else: # Decompose the link into pieces. m = self._LINK_RE.match(pieces[i]) if m is None: continue # Error flagged by _check_links (target, name) = m.groups() # Normalize the target name. if target[0] == '#': target = target[1:] target = target.replace('#', '.') target = re.sub(r'\(.*\)', '', target) # Provide a name, if it wasn't specified. if name is None: name = target else: name = name.strip() # Use docstring_linker to convert the name to html. html += translate_xref(target, name) return html def _check_links(self, errors): """ Make sure that all @{link}s are valid. We need a separate method for ths because we want to do this at parse time, not html output time. Any errors found are appended to C{errors}. """ pieces = self._LINK_SPLIT_RE.split(self._docstring) linenum = 0 for i in range(len(pieces)): if i%2 == 1 and not self._LINK_RE.match(pieces[i]): estr = 'Bad link %r' % pieces[i] errors.append(ParseError(estr, linenum, is_fatal=0)) linenum += pieces[i].count('\n') #//////////////////////////////////////////////////////////// # Plaintext Output. #//////////////////////////////////////////////////////////// # Inherit docs from ParsedDocstring. Since we don't define # to_latex, this is used when generating latex output. def to_plaintext(self, docstring_linker, **options): return self._docstring _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)') # Jeff's hack to get summary working def summary(self): # Drop tags doc = "\n".join([ row for row in self._docstring.split('\n') if not row.lstrip().startswith('@') ]) m = self._SUMMARY_RE.match(doc) if m: other = doc[m.end():] return (ParsedJavadocDocstring(m.group(1)), other != '' and not other.isspace()) else: parts = doc.strip('\n').split('\n', 1) if len(parts) == 1: summary = parts[0] other = False else: summary = parts[0] + '...' other = True return ParsedJavadocDocstring(summary), other # def concatenate(self, other): # if not isinstance(other, ParsedJavadocDocstring): # raise ValueError, 'Could not concatenate docstrings' # return ParsedJavadocDocstring(self._docstring+other._docstring) epydoc-3.0.1+dfsg/epydoc/markup/plaintext.py0000644000175000017500000000556610654406437021366 0ustar pronovicpronovic# # plaintext.py: plaintext docstring parsing # Edward Loper # # Created [04/10/01 12:00 AM] # $Id: plaintext.py 1574 2007-03-07 02:55:14Z dvarrazzo $ # """ Parser for plaintext docstrings. Plaintext docstrings are rendered as verbatim output, preserving all whitespace. """ __docformat__ = 'epytext en' from epydoc.markup import * from epydoc.util import plaintext_to_html, plaintext_to_latex def parse_docstring(docstring, errors, **options): """ @return: A pair C{(M{d}, M{e})}, where C{M{d}} is a C{ParsedDocstring} that encodes the contents of the given plaintext docstring; and C{M{e}} is a list of errors that were generated while parsing the docstring. @rtype: C{L{ParsedPlaintextDocstring}, C{list} of L{ParseError}} """ return ParsedPlaintextDocstring(docstring, **options) class ParsedPlaintextDocstring(ParsedDocstring): def __init__(self, text, **options): self._verbatim = options.get('verbatim', 1) if text is None: raise ValueError, 'Bad text value (expected a str)' self._text = text def to_html(self, docstring_linker, **options): if options.get('verbatim', self._verbatim) == 0: return plaintext_to_html(self.to_plaintext(docstring_linker)) else: return ParsedDocstring.to_html(self, docstring_linker, **options) def to_latex(self, docstring_linker, **options): if options.get('verbatim', self._verbatim) == 0: return plaintext_to_latex(self.to_plaintext(docstring_linker)) else: return ParsedDocstring.to_latex(self, docstring_linker, **options) def to_plaintext(self, docstring_linker, **options): if 'indent' in options: indent = options['indent'] lines = self._text.split('\n') return '\n'.join([' '*indent+l for l in lines])+'\n' return self._text+'\n' _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?(?:\.(\s|$)|[\n][\t ]*[\n]))') def summary(self): m = self._SUMMARY_RE.match(self._text) if m: other = self._text[m.end():] return (ParsedPlaintextDocstring(m.group(1), verbatim=0), other != '' and not other.isspace()) else: parts = self._text.strip('\n').split('\n', 1) if len(parts) == 1: summary = parts[0] other = False else: summary = parts[0] + '...' other = True return ParsedPlaintextDocstring(summary, verbatim=0), other # def concatenate(self, other): # if not isinstance(other, ParsedPlaintextDocstring): # raise ValueError, 'Could not concatenate docstrings' # text = self._text+other._text # options = self._options.copy() # options.update(other._options) # return ParsedPlaintextDocstring(text, options) epydoc-3.0.1+dfsg/epydoc/apidoc.py0000644000175000017500000026447710747623122017321 0ustar pronovicpronovic# epydoc -- API Documentation Classes # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: apidoc.py 1675 2008-01-29 17:12:56Z edloper $ """ Classes for encoding API documentation about Python programs. These classes are used as a common representation for combining information derived from introspection and from parsing. The API documentation for a Python program is encoded using a graph of L{APIDoc} objects, each of which encodes information about a single Python variable or value. C{APIDoc} has two direct subclasses: L{VariableDoc}, for documenting variables; and L{ValueDoc}, for documenting values. The C{ValueDoc} class is subclassed further, to define the different pieces of information that should be recorded about each value type: G{classtree: APIDoc} The distinction between variables and values is intentionally made explicit. This allows us to distinguish information about a variable itself (such as whether it should be considered 'public' in its containing namespace) from information about the value it contains (such as what type the value has). This distinction is also important because several variables can contain the same value: each variable should be described by a separate C{VariableDoc}; but we only need one C{ValueDoc}, since they share a single value. @todo: Add a cache to canonical name lookup? """ __docformat__ = 'epytext en' ###################################################################### ## Imports ###################################################################### import types, re, os.path, pickle from epydoc import log import epydoc import __builtin__ from epydoc.compat import * # Backwards compatibility from epydoc.util import decode_with_backslashreplace, py_src_filename import epydoc.markup.pyval_repr ###################################################################### # Dotted Names ###################################################################### class DottedName: """ A sequence of identifiers, separated by periods, used to name a Python variable, value, or argument. The identifiers that make up a dotted name can be accessed using the indexing operator: >>> name = DottedName('epydoc', 'api_doc', 'DottedName') >>> print name epydoc.apidoc.DottedName >>> name[1] 'api_doc' """ UNREACHABLE = "??" _IDENTIFIER_RE = re.compile("""(?x) (%s | # UNREACHABLE marker, or.. (script-)? # Prefix: script (not a module) \w+ # Identifier (yes, identifiers starting with a # digit are allowed. See SF bug #1649347) '?) # Suffix: submodule that is shadowed by a var (-\d+)? # Suffix: unreachable vals with the same name $""" % re.escape(UNREACHABLE)) class InvalidDottedName(ValueError): """ An exception raised by the DottedName constructor when one of its arguments is not a valid dotted name. """ _ok_identifiers = set() """A cache of identifier strings that have been checked against _IDENTIFIER_RE and found to be acceptable.""" def __init__(self, *pieces, **options): """ Construct a new dotted name from the given sequence of pieces, each of which can be either a C{string} or a C{DottedName}. Each piece is divided into a sequence of identifiers, and these sequences are combined together (in order) to form the identifier sequence for the new C{DottedName}. If a piece contains a string, then it is divided into substrings by splitting on periods, and each substring is checked to see if it is a valid identifier. As an optimization, C{pieces} may also contain a single tuple of values. In that case, that tuple will be used as the C{DottedName}'s identifiers; it will I{not} be checked to see if it's valid. @kwparam strict: if true, then raise an L{InvalidDottedName} if the given name is invalid. """ if len(pieces) == 1 and isinstance(pieces[0], tuple): self._identifiers = pieces[0] # Optimization return if len(pieces) == 0: raise DottedName.InvalidDottedName('Empty DottedName') self._identifiers = [] for piece in pieces: if isinstance(piece, DottedName): self._identifiers += piece._identifiers elif isinstance(piece, basestring): for subpiece in piece.split('.'): if piece not in self._ok_identifiers: if not self._IDENTIFIER_RE.match(subpiece): if options.get('strict'): raise DottedName.InvalidDottedName( 'Bad identifier %r' % (piece,)) else: log.warning("Identifier %r looks suspicious; " "using it anyway." % piece) self._ok_identifiers.add(piece) self._identifiers.append(subpiece) else: raise TypeError('Bad identifier %r: expected ' 'DottedName or str' % (piece,)) self._identifiers = tuple(self._identifiers) def __repr__(self): idents = [`ident` for ident in self._identifiers] return 'DottedName(' + ', '.join(idents) + ')' def __str__(self): """ Return the dotted name as a string formed by joining its identifiers with periods: >>> print DottedName('epydoc', 'api_doc', DottedName') epydoc.apidoc.DottedName """ return '.'.join(self._identifiers) def __add__(self, other): """ Return a new C{DottedName} whose identifier sequence is formed by adding C{other}'s identifier sequence to C{self}'s. """ if isinstance(other, (basestring, DottedName)): return DottedName(self, other) else: return DottedName(self, *other) def __radd__(self, other): """ Return a new C{DottedName} whose identifier sequence is formed by adding C{self}'s identifier sequence to C{other}'s. """ if isinstance(other, (basestring, DottedName)): return DottedName(other, self) else: return DottedName(*(list(other)+[self])) def __getitem__(self, i): """ Return the C{i}th identifier in this C{DottedName}. If C{i} is a non-empty slice, then return a C{DottedName} built from the identifiers selected by the slice. If C{i} is an empty slice, return an empty list (since empty C{DottedName}s are not valid). """ if isinstance(i, types.SliceType): pieces = self._identifiers[i.start:i.stop] if pieces: return DottedName(pieces) else: return [] else: return self._identifiers[i] def __hash__(self): return hash(self._identifiers) def __cmp__(self, other): """ Compare this dotted name to C{other}. Two dotted names are considered equal if their identifier subsequences are equal. Ordering between dotted names is lexicographic, in order of identifier from left to right. """ if not isinstance(other, DottedName): return -1 return cmp(self._identifiers, other._identifiers) def __len__(self): """ Return the number of identifiers in this dotted name. """ return len(self._identifiers) def container(self): """ Return the DottedName formed by removing the last identifier from this dotted name's identifier sequence. If this dotted name only has one name in its identifier sequence, return C{None} instead. """ if len(self._identifiers) == 1: return None else: return DottedName(*self._identifiers[:-1]) def dominates(self, name, strict=False): """ Return true if this dotted name is equal to a prefix of C{name}. If C{strict} is true, then also require that C{self!=name}. >>> DottedName('a.b').dominates(DottedName('a.b.c.d')) True """ len_self = len(self._identifiers) len_name = len(name._identifiers) if (len_self > len_name) or (strict and len_self == len_name): return False # The following is redundant (the first clause is implied by # the second), but is done as an optimization. return ((self._identifiers[0] == name._identifiers[0]) and self._identifiers == name._identifiers[:len_self]) def contextualize(self, context): """ If C{self} and C{context} share a common ancestor, then return a name for C{self}, relative to that ancestor. If they do not share a common ancestor (or if C{context} is C{UNKNOWN}), then simply return C{self}. This is used to generate shorter versions of dotted names in cases where users can infer the intended target from the context. @type context: L{DottedName} @rtype: L{DottedName} """ if context is UNKNOWN or not context or len(self) <= 1: return self if self[0] == context[0]: return self[1:].contextualize(context[1:]) else: return self # Find the first index where self & context differ. for i in range(min(len(context), len(self))): if self._identifiers[i] != context._identifiers[i]: first_difference = i break else: first_difference = i+1 # Strip off anything before that index. if first_difference == 0: return self elif first_difference == len(self): return self[-1:] else: return self[first_difference:] ###################################################################### # UNKNOWN Value ###################################################################### class _Sentinel: """ A unique value that won't compare equal to any other value. This class is used to create L{UNKNOWN}. """ def __init__(self, name): self.name = name def __repr__(self): return '<%s>' % self.name def __nonzero__(self): raise ValueError('Sentinel value <%s> can not be used as a boolean' % self.name) UNKNOWN = _Sentinel('UNKNOWN') """A special value used to indicate that a given piece of information about an object is unknown. This is used as the default value for all instance variables.""" ###################################################################### # API Documentation Objects: Abstract Base Classes ###################################################################### class APIDoc(object): """ API documentation information for a single element of a Python program. C{APIDoc} itself is an abstract base class; subclasses are used to specify what information should be recorded about each type of program element. In particular, C{APIDoc} has two direct subclasses, C{VariableDoc} for documenting variables and C{ValueDoc} for documenting values; and the C{ValueDoc} class is subclassed further for different value types. Each C{APIDoc} subclass specifies the set of attributes that should be used to record information about the corresponding program element type. The default value for each attribute is stored in the class; these default values can then be overridden with instance variables. Most attributes use the special value L{UNKNOWN} as their default value, to indicate that the correct value for that attribute has not yet been determined. This makes it easier to merge two C{APIDoc} objects that are documenting the same element (in particular, to merge information about an element that was derived from parsing with information that was derived from introspection). For all attributes with boolean values, use only the constants C{True} and C{False} to designate true and false. In particular, do I{not} use other values that evaluate as true or false, such as C{2} or C{()}. This restriction makes it easier to handle C{UNKNOWN} values. For example, to test if a boolean attribute is C{True} or C{UNKNOWN}, use 'C{attrib in (True, UNKNOWN)}' or 'C{attrib is not False}'. Two C{APIDoc} objects describing the same object can be X{merged}, using the method L{merge_and_overwrite(other)}. After two C{APIDoc}s are merged, any changes to one will be reflected in the other. This is accomplished by setting the two C{APIDoc} objects to use a shared instance dictionary. See the documentation for L{merge_and_overwrite} for more information, and some important caveats about hashing. """ #{ Docstrings docstring = UNKNOWN """@ivar: The documented item's docstring. @type: C{string} or C{None}""" docstring_lineno = UNKNOWN """@ivar: The line number on which the documented item's docstring begins. @type: C{int}""" #} end of "docstrings" group #{ Information Extracted from Docstrings descr = UNKNOWN """@ivar: A description of the documented item, extracted from its docstring. @type: L{ParsedDocstring}""" summary = UNKNOWN """@ivar: A summary description of the documented item, extracted from its docstring. @type: L{ParsedDocstring}""" other_docs = UNKNOWN """@ivar: A flag indicating if the entire L{docstring} body (except tags if any) is entirely included in the L{summary}. @type: C{bool}""" metadata = UNKNOWN """@ivar: Metadata about the documented item, extracted from fields in its docstring. I{Currently} this is encoded as a list of tuples C{(field, arg, descr)}. But that may change. @type: C{(str, str, L{ParsedDocstring})}""" extra_docstring_fields = UNKNOWN """@ivar: A list of new docstring fields tags that are defined by the documented item's docstring. These new field tags can be used by this item or by any item it contains. @type: L{DocstringField }""" #} end of "information extracted from docstrings" group #{ Source Information docs_extracted_by = UNKNOWN # 'parser' or 'introspecter' or 'both' """@ivar: Information about where the information contained by this C{APIDoc} came from. Can be one of C{'parser'}, C{'introspector'}, or C{'both'}. @type: C{str}""" #} end of "source information" group def __init__(self, **kwargs): """ Construct a new C{APIDoc} object. Keyword arguments may be used to initialize the new C{APIDoc}'s attributes. @raise TypeError: If a keyword argument is specified that does not correspond to a valid attribute for this (sub)class of C{APIDoc}. """ if epydoc.DEBUG: for key in kwargs: if key[0] != '_' and not hasattr(self.__class__, key): raise TypeError('%s got unexpected arg %r' % (self.__class__.__name__, key)) self.__dict__.update(kwargs) def _debug_setattr(self, attr, val): """ Modify an C{APIDoc}'s attribute. This is used when L{epydoc.DEBUG} is true, to make sure we don't accidentally set any inappropriate attributes on C{APIDoc} objects. @raise AttributeError: If C{attr} is not a valid attribute for this (sub)class of C{APIDoc}. (C{attr} is considered a valid attribute iff C{self.__class__} defines an attribute with that name.) """ # Don't intercept special assignments like __class__, or # assignments to private variables. if attr.startswith('_'): return object.__setattr__(self, attr, val) if not hasattr(self, attr): raise AttributeError('%s does not define attribute %r' % (self.__class__.__name__, attr)) self.__dict__[attr] = val if epydoc.DEBUG: __setattr__ = _debug_setattr def __repr__(self): return '<%s>' % self.__class__.__name__ def pp(self, doublespace=0, depth=5, exclude=(), include=()): """ Return a pretty-printed string representation for the information contained in this C{APIDoc}. """ return pp_apidoc(self, doublespace, depth, exclude, include) __str__ = pp def specialize_to(self, cls): """ Change C{self}'s class to C{cls}. C{cls} must be a subclass of C{self}'s current class. For example, if a generic C{ValueDoc} was created for a value, and it is determined that the value is a routine, you can update its class with: >>> valdoc.specialize_to(RoutineDoc) """ if not issubclass(cls, self.__class__): raise ValueError('Can not specialize to %r' % cls) # Update the class. self.__class__ = cls # Update the class of any other apidoc's in the mergeset. if self.__mergeset is not None: for apidoc in self.__mergeset: apidoc.__class__ = cls # Re-initialize self, in case the subclass constructor does # any special processing on its arguments. self.__init__(**self.__dict__) __has_been_hashed = False """True iff L{self.__hash__()} has ever been called.""" def __hash__(self): self.__has_been_hashed = True return id(self.__dict__) def __cmp__(self, other): if not isinstance(other, APIDoc): return -1 if self.__dict__ is other.__dict__: return 0 name_cmp = cmp(self.canonical_name, other.canonical_name) if name_cmp == 0: return -1 else: return name_cmp def is_detailed(self): """ Does this object deserve a box with extra details? @return: True if the object needs extra details, else False. @rtype: C{bool} """ if self.other_docs is True: return True if self.metadata is not UNKNOWN: return bool(self.metadata) __mergeset = None """The set of all C{APIDoc} objects that have been merged with this C{APIDoc} (using L{merge_and_overwrite()}). Each C{APIDoc} in this set shares a common instance dictionary (C{__dict__}).""" def merge_and_overwrite(self, other, ignore_hash_conflict=False): """ Combine C{self} and C{other} into a X{merged object}, such that any changes made to one will affect the other. Any attributes that C{other} had before merging will be discarded. This is accomplished by copying C{self.__dict__} over C{other.__dict__} and C{self.__class__} over C{other.__class__}. Care must be taken with this method, since it modifies the hash value of C{other}. To help avoid the problems that this can cause, C{merge_and_overwrite} will raise an exception if C{other} has ever been hashed, unless C{ignore_hash_conflict} is True. Note that adding C{other} to a dictionary, set, or similar data structure will implicitly cause it to be hashed. If you do set C{ignore_hash_conflict} to True, then any existing data structures that rely on C{other}'s hash staying constant may become corrupted. @return: C{self} @raise ValueError: If C{other} has ever been hashed. """ # If we're already merged, then there's nothing to do. if (self.__dict__ is other.__dict__ and self.__class__ is other.__class__): return self if other.__has_been_hashed and not ignore_hash_conflict: raise ValueError("%r has already been hashed! Merging it " "would cause its has value to change." % other) # If other was itself already merged with anything, # then we need to merge those too. a,b = (self.__mergeset, other.__mergeset) mergeset = (self.__mergeset or [self]) + (other.__mergeset or [other]) other.__dict__.clear() for apidoc in mergeset: #if apidoc is self: pass apidoc.__class__ = self.__class__ apidoc.__dict__ = self.__dict__ self.__mergeset = mergeset # Sanity chacks. assert self in mergeset and other in mergeset for apidoc in mergeset: assert apidoc.__dict__ is self.__dict__ # Return self. return self def apidoc_links(self, **filters): """ Return a list of all C{APIDoc}s that are directly linked from this C{APIDoc} (i.e., are contained or pointed to by one or more of this C{APIDoc}'s attributes.) Keyword argument C{filters} can be used to selectively exclude certain categories of attribute value. For example, using C{includes=False} will exclude variables that were imported from other modules; and C{subclasses=False} will exclude subclasses. The filter categories currently supported by epydoc are: - C{imports}: Imported variables. - C{packages}: Containing packages for modules. - C{submodules}: Contained submodules for packages. - C{bases}: Bases for classes. - C{subclasses}: Subclasses for classes. - C{variables}: All variables. - C{private}: Private variables. - C{overrides}: Points from class variables to the variables they override. This filter is False by default. """ return [] def reachable_valdocs(root, **filters): """ Return a list of all C{ValueDoc}s that can be reached, directly or indirectly from the given root list of C{ValueDoc}s. @param filters: A set of filters that can be used to prevent C{reachable_valdocs} from following specific link types when looking for C{ValueDoc}s that can be reached from the root set. See C{APIDoc.apidoc_links} for a more complete description. """ apidoc_queue = list(root) val_set = set() var_set = set() while apidoc_queue: api_doc = apidoc_queue.pop() if isinstance(api_doc, ValueDoc): val_set.add(api_doc) else: var_set.add(api_doc) apidoc_queue.extend([v for v in api_doc.apidoc_links(**filters) if v not in val_set and v not in var_set]) return val_set ###################################################################### # Variable Documentation Objects ###################################################################### class VariableDoc(APIDoc): """ API documentation information about a single Python variable. @note: The only time a C{VariableDoc} will have its own docstring is if that variable was created using an assignment statement, and that assignment statement had a docstring-comment or was followed by a pseudo-docstring. """ #{ Basic Variable Information name = UNKNOWN """@ivar: The name of this variable in its containing namespace. @type: C{str}""" container = UNKNOWN """@ivar: API documentation for the namespace that contains this variable. @type: L{ValueDoc}""" canonical_name = UNKNOWN """@ivar: A dotted name that serves as a unique identifier for this C{VariableDoc}. It should be formed by concatenating the C{VariableDoc}'s C{container} with its C{name}. @type: L{DottedName}""" value = UNKNOWN """@ivar: The API documentation for this variable's value. @type: L{ValueDoc}""" #} #{ Information Extracted from Docstrings type_descr = UNKNOWN """@ivar: A description of the variable's expected type, extracted from its docstring. @type: L{ParsedDocstring}""" #} end of "information extracted from docstrings" group #{ Information about Imported Variables imported_from = UNKNOWN """@ivar: The fully qualified dotted name of the variable that this variable's value was imported from. This attribute should only be defined if C{is_instvar} is true. @type: L{DottedName}""" is_imported = UNKNOWN """@ivar: Was this variable's value imported from another module? (Exception: variables that are explicitly included in __all__ have C{is_imported} set to C{False}, even if they are in fact imported.) @type: C{bool}""" #} end of "information about imported variables" group #{ Information about Variables in Classes is_instvar = UNKNOWN """@ivar: If true, then this variable is an instance variable; if false, then this variable is a class variable. This attribute should only be defined if the containing namespace is a class @type: C{bool}""" overrides = UNKNOWN # [XXX] rename -- don't use a verb. """@ivar: The API documentation for the variable that is overridden by this variable. This attribute should only be defined if the containing namespace is a class. @type: L{VariableDoc}""" #} end of "information about variables in classes" group #{ Flags is_alias = UNKNOWN """@ivar: Is this variable an alias for another variable with the same value? If so, then this variable will be dispreferred when assigning canonical names. @type: C{bool}""" is_public = UNKNOWN """@ivar: Is this variable part of its container's public API? @type: C{bool}""" #} end of "flags" group def __init__(self, **kwargs): APIDoc.__init__(self, **kwargs) if self.is_public is UNKNOWN and self.name is not UNKNOWN: self.is_public = (not self.name.startswith('_') or self.name.endswith('_')) def __repr__(self): if self.canonical_name is not UNKNOWN: return '<%s %s>' % (self.__class__.__name__, self.canonical_name) if self.name is not UNKNOWN: return '<%s %s>' % (self.__class__.__name__, self.name) else: return '<%s>' % self.__class__.__name__ def _get_defining_module(self): if self.container is UNKNOWN: return UNKNOWN return self.container.defining_module defining_module = property(_get_defining_module, doc=""" A read-only property that can be used to get the variable's defining module. This is defined as the defining module of the variable's container.""") def apidoc_links(self, **filters): # nb: overrides filter is *False* by default. if (filters.get('overrides', False) and (self.overrides not in (None, UNKNOWN))): overrides = [self.overrides] else: overrides = [] if self.value in (None, UNKNOWN): return []+overrides else: return [self.value]+overrides def is_detailed(self): pval = super(VariableDoc, self).is_detailed() if pval or self.value in (None, UNKNOWN): return pval if (self.overrides not in (None, UNKNOWN) and isinstance(self.value, RoutineDoc)): return True if isinstance(self.value, GenericValueDoc): # [XX] This is a little hackish -- we assume that the # summary lines will have SUMMARY_REPR_LINELEN chars, # that len(name) of those will be taken up by the name, # and that 3 of those will be taken up by " = " between # the name & val. Note that if any docwriter uses a # different formula for maxlen for this, then it will # not get the right value for is_detailed(). maxlen = self.value.SUMMARY_REPR_LINELEN-3-len(self.name) return (not self.value.summary_pyval_repr(maxlen).is_complete) else: return self.value.is_detailed() ###################################################################### # Value Documentation Objects ###################################################################### class ValueDoc(APIDoc): """ API documentation information about a single Python value. """ canonical_name = UNKNOWN """@ivar: A dotted name that serves as a unique identifier for this C{ValueDoc}'s value. If the value can be reached using a single sequence of identifiers (given the appropriate imports), then that sequence of identifiers is used as its canonical name. If the value can be reached by multiple sequences of identifiers (i.e., if it has multiple aliases), then one of those sequences of identifiers is used. If the value cannot be reached by any sequence of identifiers (e.g., if it was used as a base class but then its variable was deleted), then its canonical name will start with C{'??'}. If necessary, a dash followed by a number will be appended to the end of a non-reachable identifier to make its canonical name unique. When possible, canonical names are chosen when new C{ValueDoc}s are created. However, this is sometimes not possible. If a canonical name can not be chosen when the C{ValueDoc} is created, then one will be assigned by L{assign_canonical_names() }. @type: L{DottedName}""" #{ Value Representation pyval = UNKNOWN """@ivar: A pointer to the actual Python object described by this C{ValueDoc}. This is used to display the value (e.g., when describing a variable.) Use L{pyval_repr()} to generate a plaintext string representation of this value. @type: Python object""" parse_repr = UNKNOWN """@ivar: A text representation of this value, extracted from parsing its source code. This representation may not accurately reflect the actual value (e.g., if the value was modified after the initial assignment). @type: C{unicode}""" REPR_MAXLINES = 5 """@cvar: The maximum number of lines of text that should be generated by L{pyval_repr()}. If the string representation does not fit in this number of lines, an ellpsis marker (...) will be placed at the end of the formatted representation.""" REPR_LINELEN = 75 """@cvar: The maximum number of characters for lines of text that should be generated by L{pyval_repr()}. Any lines that exceed this number of characters will be line-wrappped; The S{crarr} symbol will be used to indicate that the line was wrapped.""" SUMMARY_REPR_LINELEN = 75 """@cvar: The maximum number of characters for the single-line text representation generated by L{summary_pyval_repr()}. If the value's representation does not fit in this number of characters, an ellipsis marker (...) will be placed at the end of the formatted representation.""" REPR_MIN_SCORE = 0 """@cvar: The minimum score that a value representation based on L{pyval} should have in order to be used instead of L{parse_repr} as the canonical representation for this C{ValueDoc}'s value. @see: L{epydoc.markup.pyval_repr}""" #} end of "value representation" group #{ Context defining_module = UNKNOWN """@ivar: The documentation for the module that defines this value. This is used, e.g., to lookup the appropriate markup language for docstrings. For a C{ModuleDoc}, C{defining_module} should be C{self}. @type: L{ModuleDoc}""" #} end of "context group" #{ Information about Imported Variables proxy_for = None # [xx] in progress. """@ivar: If C{proxy_for} is not None, then this value was imported from another file. C{proxy_for} is the dotted name of the variable that this value was imported from. If that variable is documented, then its C{value} may contain more complete API documentation about this value. The C{proxy_for} attribute is used by the source code parser to link imported values to their source values (in particular, for base classes). When possible, these proxy C{ValueDoc}s are replaced by the imported value's C{ValueDoc} by L{link_imports()}. @type: L{DottedName}""" #} end of "information about imported variables" group #: @ivar: #: This is currently used to extract values from __all__, etc, in #: the docparser module; maybe I should specialize #: process_assignment and extract it there? Although, for __all__, #: it's not clear where I'd put the value, since I just use it to #: set private/public/imported attribs on other vars (that might not #: exist yet at the time.) toktree = UNKNOWN def __repr__(self): if self.canonical_name is not UNKNOWN: return '<%s %s>' % (self.__class__.__name__, self.canonical_name) else: return '<%s %s>' % (self.__class__.__name__, self.summary_pyval_repr().to_plaintext(None)) def __setstate__(self, state): self.__dict__ = state def __getstate__(self): """ State serializer for the pickle module. This is necessary because sometimes the C{pyval} attribute contains an un-pickleable value. """ # Construct our pickled dictionary. Maintain this dictionary # as a private attribute, so we can reuse it later, since # merged objects need to share a single dictionary. if not hasattr(self, '_ValueDoc__pickle_state'): # Make sure __pyval_repr & __summary_pyval_repr are cached: self.pyval_repr(), self.summary_pyval_repr() # Construct the dictionary; leave out 'pyval'. self.__pickle_state = self.__dict__.copy() self.__pickle_state['pyval'] = UNKNOWN if not isinstance(self, GenericValueDoc): assert self.__pickle_state != {} # Return the pickle state. return self.__pickle_state #{ Value Representation def pyval_repr(self): """ Return a formatted representation of the Python object described by this C{ValueDoc}. This representation may include data from introspection or parsing, and is authorative as 'the best way to represent a Python value.' Any lines that go beyond L{REPR_LINELEN} characters will be wrapped; and if the representation as a whole takes more than L{REPR_MAXLINES} lines, then it will be truncated (with an ellipsis marker). This function will never return L{UNKNOWN} or C{None}. @rtype: L{ColorizedPyvalRepr} """ # Use self.__pyval_repr to cache the result. if not hasattr(self, '_ValueDoc__pyval_repr'): self.__pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( self.pyval, self.parse_repr, self.REPR_MIN_SCORE, self.REPR_LINELEN, self.REPR_MAXLINES, linebreakok=True) return self.__pyval_repr def summary_pyval_repr(self, max_len=None): """ Return a single-line formatted representation of the Python object described by this C{ValueDoc}. This representation may include data from introspection or parsing, and is authorative as 'the best way to summarize a Python value.' If the representation takes more then L{SUMMARY_REPR_LINELEN} characters, then it will be truncated (with an ellipsis marker). This function will never return L{UNKNOWN} or C{None}. @rtype: L{ColorizedPyvalRepr} """ # If max_len is specified, then do *not* cache the result. if max_len is not None: return epydoc.markup.pyval_repr.colorize_pyval( self.pyval, self.parse_repr, self.REPR_MIN_SCORE, max_len, maxlines=1, linebreakok=False) # Use self.__summary_pyval_repr to cache the result. if not hasattr(self, '_ValueDoc__summary_pyval_repr'): self.__summary_pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( self.pyval, self.parse_repr, self.REPR_MIN_SCORE, self.SUMMARY_REPR_LINELEN, maxlines=1, linebreakok=False) return self.__summary_pyval_repr #} end of "value representation" group def apidoc_links(self, **filters): return [] class GenericValueDoc(ValueDoc): """ API documentation about a 'generic' value, i.e., one that does not have its own docstring or any information other than its value and parse representation. C{GenericValueDoc}s do not get assigned cannonical names. """ canonical_name = None def is_detailed(self): return (not self.summary_pyval_repr().is_complete) class NamespaceDoc(ValueDoc): """ API documentation information about a singe Python namespace value. (I.e., a module or a class). """ #{ Information about Variables variables = UNKNOWN """@ivar: The contents of the namespace, encoded as a dictionary mapping from identifiers to C{VariableDoc}s. This dictionary contains all names defined by the namespace, including imported variables, aliased variables, and variables inherited from base classes (once L{inherit_docs() } has added them). @type: C{dict} from C{string} to L{VariableDoc}""" sorted_variables = UNKNOWN """@ivar: A list of all variables defined by this namespace, in sorted order. The elements of this list should exactly match the values of L{variables}. The sort order for this list is defined as follows: - Any variables listed in a C{@sort} docstring field are listed in the order given by that field. - These are followed by any variables that were found while parsing the source code, in the order in which they were defined in the source file. - Finally, any remaining variables are listed in alphabetical order. @type: C{list} of L{VariableDoc}""" sort_spec = UNKNOWN """@ivar: The order in which variables should be listed, encoded as a list of names. Any variables whose names are not included in this list should be listed alphabetically, following the variables that are included. @type: C{list} of C{str}""" group_specs = UNKNOWN """@ivar: The groups that are defined by this namespace's docstrings. C{group_specs} is encoded as an ordered list of tuples C{(group_name, elt_names)}, where C{group_name} is the name of a group and C{elt_names} is a list of element names in that group. (An element can be a variable or a submodule.) A '*' in an element name will match any string of characters. @type: C{list} of C{(str,list)}""" variable_groups = UNKNOWN """@ivar: A dictionary specifying what group each variable belongs to. The keys of the dictionary are group names, and the values are lists of C{VariableDoc}s. The order that groups should be listed in should be taken from L{group_specs}. @type: C{dict} from C{str} to C{list} of L{VariableDoc}""" #} end of group "information about variables" def __init__(self, **kwargs): kwargs.setdefault('variables', {}) APIDoc.__init__(self, **kwargs) assert self.variables is not UNKNOWN def is_detailed(self): return True def apidoc_links(self, **filters): variables = filters.get('variables', True) imports = filters.get('imports', True) private = filters.get('private', True) if variables and imports and private: return self.variables.values() # list the common case first. elif not variables: return [] elif not imports and not private: return [v for v in self.variables.values() if v.is_imported != True and v.is_public != False] elif not private: return [v for v in self.variables.values() if v.is_public != False] elif not imports: return [v for v in self.variables.values() if v.is_imported != True] assert 0, 'this line should be unreachable' def init_sorted_variables(self): """ Initialize the L{sorted_variables} attribute, based on the L{variables} and L{sort_spec} attributes. This should usually be called after all variables have been added to C{variables} (including any inherited variables for classes). """ unsorted = self.variables.copy() self.sorted_variables = [] # Add any variables that are listed in sort_spec if self.sort_spec is not UNKNOWN: unused_idents = set(self.sort_spec) for ident in self.sort_spec: if ident in unsorted: self.sorted_variables.append(unsorted.pop(ident)) unused_idents.discard(ident) elif '*' in ident: regexp = re.compile('^%s$' % ident.replace('*', '(.*)')) # sort within matching group? for name, var_doc in unsorted.items(): if regexp.match(name): self.sorted_variables.append(unsorted.pop(name)) unused_idents.discard(ident) for ident in unused_idents: if ident not in ['__all__', '__docformat__', '__path__']: log.warning("@sort: %s.%s not found" % (self.canonical_name, ident)) # Add any remaining variables in alphabetical order. var_docs = unsorted.items() var_docs.sort() for name, var_doc in var_docs: self.sorted_variables.append(var_doc) def init_variable_groups(self): """ Initialize the L{variable_groups} attribute, based on the L{sorted_variables} and L{group_specs} attributes. """ if self.sorted_variables is UNKNOWN: self.init_sorted_variables() assert len(self.sorted_variables) == len(self.variables) elts = [(v.name, v) for v in self.sorted_variables] self._unused_groups = dict([(n,set(i)) for (n,i) in self.group_specs]) self.variable_groups = self._init_grouping(elts) def group_names(self): """ Return a list of the group names defined by this namespace, in the order in which they should be listed, with no duplicates. """ name_list = [''] name_set = set() for name, spec in self.group_specs: if name not in name_set: name_set.add(name) name_list.append(name) return name_list def _init_grouping(self, elts): """ Divide a given a list of APIDoc objects into groups, as specified by L{self.group_specs}. @param elts: A list of tuples C{(name, apidoc)}. @return: A list of tuples C{(groupname, elts)}, where C{groupname} is the name of a group and C{elts} is a list of C{APIDoc}s in that group. The first tuple has name C{''}, and is used for ungrouped elements. The remaining tuples are listed in the order that they appear in C{self.group_specs}. Within each tuple, the elements are listed in the order that they appear in C{api_docs}. """ # Make the common case fast. if len(self.group_specs) == 0: return {'': [elt[1] for elt in elts]} ungrouped = set([elt_doc for (elt_name, elt_doc) in elts]) ungrouped = dict(elts) groups = {} for elt_name, elt_doc in elts: for (group_name, idents) in self.group_specs: group = groups.setdefault(group_name, []) unused_groups = self._unused_groups[group_name] for ident in idents: if re.match('^%s$' % ident.replace('*', '(.*)'), elt_name): unused_groups.discard(ident) if elt_name in ungrouped: group.append(ungrouped.pop(elt_name)) else: log.warning("%s.%s in multiple groups" % (self.canonical_name, elt_name)) # Convert ungrouped from an unordered set to an ordered list. groups[''] = [elt_doc for (elt_name, elt_doc) in elts if elt_name in ungrouped] return groups def report_unused_groups(self): """ Issue a warning for any @group items that were not used by L{_init_grouping()}. """ for (group, unused_idents) in self._unused_groups.items(): for ident in unused_idents: log.warning("@group %s: %s.%s not found" % (group, self.canonical_name, ident)) class ModuleDoc(NamespaceDoc): """ API documentation information about a single module. """ #{ Information about the Module filename = UNKNOWN """@ivar: The name of the file that defines the module. @type: C{string}""" docformat = UNKNOWN """@ivar: The markup language used by docstrings in this module. @type: C{string}""" #{ Information about Submodules submodules = UNKNOWN """@ivar: Modules contained by this module (if this module is a package). (Note: on rare occasions, a module may have a submodule that is shadowed by a variable with the same name.) @type: C{list} of L{ModuleDoc}""" submodule_groups = UNKNOWN """@ivar: A dictionary specifying what group each submodule belongs to. The keys of the dictionary are group names, and the values are lists of C{ModuleDoc}s. The order that groups should be listed in should be taken from L{group_specs}. @type: C{dict} from C{str} to C{list} of L{ModuleDoc}""" #{ Information about Packages package = UNKNOWN """@ivar: API documentation for the module's containing package. @type: L{ModuleDoc}""" is_package = UNKNOWN """@ivar: True if this C{ModuleDoc} describes a package. @type: C{bool}""" path = UNKNOWN """@ivar: If this C{ModuleDoc} describes a package, then C{path} contains a list of directories that constitute its path (i.e., the value of its C{__path__} variable). @type: C{list} of C{str}""" #{ Information about Imported Variables imports = UNKNOWN """@ivar: A list of the source names of variables imported into this module. This is used to construct import graphs. @type: C{list} of L{DottedName}""" #} def apidoc_links(self, **filters): val_docs = NamespaceDoc.apidoc_links(self, **filters) if (filters.get('packages', True) and self.package not in (None, UNKNOWN)): val_docs.append(self.package) if (filters.get('submodules', True) and self.submodules not in (None, UNKNOWN)): val_docs += self.submodules return val_docs def init_submodule_groups(self): """ Initialize the L{submodule_groups} attribute, based on the L{submodules} and L{group_specs} attributes. """ if self.submodules in (None, UNKNOWN): return self.submodules = sorted(self.submodules, key=lambda m:m.canonical_name) elts = [(m.canonical_name[-1], m) for m in self.submodules] self.submodule_groups = self._init_grouping(elts) def select_variables(self, group=None, value_type=None, public=None, imported=None, detailed=None): """ Return a specified subset of this module's L{sorted_variables} list. If C{value_type} is given, then only return variables whose values have the specified type. If C{group} is given, then only return variables that belong to the specified group. @require: The L{sorted_variables}, L{variable_groups}, and L{submodule_groups} attributes must be initialized before this method can be used. See L{init_sorted_variables()}, L{init_variable_groups()}, and L{init_submodule_groups()}. @param value_type: A string specifying the value type for which variables should be returned. Valid values are: - 'class' - variables whose values are classes or types. - 'function' - variables whose values are functions. - 'other' - variables whose values are not classes, exceptions, types, or functions. @type value_type: C{string} @param group: The name of the group for which variables should be returned. A complete list of the groups defined by this C{ModuleDoc} is available in the L{group_names} instance variable. The first element of this list is always the special group name C{''}, which is used for variables that do not belong to any group. @type group: C{string} @param detailed: If True (False), return only the variables deserving (not deserving) a detailed informative box. If C{None}, don't care. @type detailed: C{bool} """ if (self.sorted_variables is UNKNOWN or self.variable_groups is UNKNOWN): raise ValueError('sorted_variables and variable_groups ' 'must be initialized first.') if group is None: var_list = self.sorted_variables else: var_list = self.variable_groups.get(group, self.sorted_variables) # Public/private filter (Count UNKNOWN as public) if public is True: var_list = [v for v in var_list if v.is_public is not False] elif public is False: var_list = [v for v in var_list if v.is_public is False] # Imported filter (Count UNKNOWN as non-imported) if imported is True: var_list = [v for v in var_list if v.is_imported is True] elif imported is False: var_list = [v for v in var_list if v.is_imported is not True] # Detailed filter if detailed is True: var_list = [v for v in var_list if v.is_detailed() is True] elif detailed is False: var_list = [v for v in var_list if v.is_detailed() is not True] # [xx] Modules are not currently included in any of these # value types. if value_type is None: return var_list elif value_type == 'class': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, ClassDoc))] elif value_type == 'function': return [var_doc for var_doc in var_list if isinstance(var_doc.value, RoutineDoc)] elif value_type == 'other': return [var_doc for var_doc in var_list if not isinstance(var_doc.value, (ClassDoc, RoutineDoc, ModuleDoc))] else: raise ValueError('Bad value type %r' % value_type) class ClassDoc(NamespaceDoc): """ API documentation information about a single class. """ #{ Information about Base Classes bases = UNKNOWN """@ivar: API documentation for the class's base classes. @type: C{list} of L{ClassDoc}""" #{ Information about Subclasses subclasses = UNKNOWN """@ivar: API documentation for the class's known subclasses. @type: C{list} of L{ClassDoc}""" #} def apidoc_links(self, **filters): val_docs = NamespaceDoc.apidoc_links(self, **filters) if (filters.get('bases', True) and self.bases not in (None, UNKNOWN)): val_docs += self.bases if (filters.get('subclasses', True) and self.subclasses not in (None, UNKNOWN)): val_docs += self.subclasses return val_docs def is_type(self): if self.canonical_name == DottedName('type'): return True if self.bases is UNKNOWN: return False for base in self.bases: if isinstance(base, ClassDoc) and base.is_type(): return True return False def is_exception(self): if self.canonical_name == DottedName('Exception'): return True if self.bases is UNKNOWN: return False for base in self.bases: if isinstance(base, ClassDoc) and base.is_exception(): return True return False def is_newstyle_class(self): if self.canonical_name == DottedName('object'): return True if self.bases is UNKNOWN: return False for base in self.bases: if isinstance(base, ClassDoc) and base.is_newstyle_class(): return True return False def mro(self, warn_about_bad_bases=False): if self.is_newstyle_class(): return self._c3_mro(warn_about_bad_bases) else: return self._dfs_bases([], set(), warn_about_bad_bases) def _dfs_bases(self, mro, seen, warn_about_bad_bases): if self in seen: return mro mro.append(self) seen.add(self) if self.bases is not UNKNOWN: for base in self.bases: if isinstance(base, ClassDoc) and base.proxy_for is None: base._dfs_bases(mro, seen, warn_about_bad_bases) elif warn_about_bad_bases: self._report_bad_base(base) return mro def _c3_mro(self, warn_about_bad_bases): """ Compute the class precedence list (mro) according to C3. @seealso: U{http://www.python.org/2.3/mro.html} """ bases = [base for base in self.bases if isinstance(base, ClassDoc)] if len(bases) != len(self.bases) and warn_about_bad_bases: for base in self.bases: if (not isinstance(base, ClassDoc) or base.proxy_for is not None): self._report_bad_base(base) w = [warn_about_bad_bases]*len(bases) return self._c3_merge([[self]] + map(ClassDoc._c3_mro, bases, w) + [list(bases)]) def _report_bad_base(self, base): if not isinstance(base, ClassDoc): if not isinstance(base, GenericValueDoc): base_name = base.canonical_name elif base.parse_repr is not UNKNOWN: base_name = base.parse_repr else: base_name = '%r' % base log.warning("%s's base %s is not a class" % (self.canonical_name, base_name)) elif base.proxy_for is not None: log.warning("No information available for %s's base %s" % (self.canonical_name, base.proxy_for)) def _c3_merge(self, seqs): """ Helper function for L{_c3_mro}. """ res = [] while 1: nonemptyseqs=[seq for seq in seqs if seq] if not nonemptyseqs: return res for seq in nonemptyseqs: # find merge candidates among seq heads cand = seq[0] nothead=[s for s in nonemptyseqs if cand in s[1:]] if nothead: cand=None #reject candidate else: break if not cand: raise "Inconsistent hierarchy" res.append(cand) for seq in nonemptyseqs: # remove cand if seq[0] == cand: del seq[0] def select_variables(self, group=None, value_type=None, inherited=None, public=None, imported=None, detailed=None): """ Return a specified subset of this class's L{sorted_variables} list. If C{value_type} is given, then only return variables whose values have the specified type. If C{group} is given, then only return variables that belong to the specified group. If C{inherited} is True, then only return inherited variables; if C{inherited} is False, then only return local variables. @require: The L{sorted_variables} and L{variable_groups} attributes must be initialized before this method can be used. See L{init_sorted_variables()} and L{init_variable_groups()}. @param value_type: A string specifying the value type for which variables should be returned. Valid values are: - 'instancemethod' - variables whose values are instance methods. - 'classmethod' - variables whose values are class methods. - 'staticmethod' - variables whose values are static methods. - 'properties' - variables whose values are properties. - 'class' - variables whose values are nested classes (including exceptions and types). - 'instancevariable' - instance variables. This includes any variables that are explicitly marked as instance variables with docstring fields; and variables with docstrings that are initialized in the constructor. - 'classvariable' - class variables. This includes any variables that are not included in any of the above categories. @type value_type: C{string} @param group: The name of the group for which variables should be returned. A complete list of the groups defined by this C{ClassDoc} is available in the L{group_names} instance variable. The first element of this list is always the special group name C{''}, which is used for variables that do not belong to any group. @type group: C{string} @param inherited: If C{None}, then return both inherited and local variables; if C{True}, then return only inherited variables; if C{False}, then return only local variables. @param detailed: If True (False), return only the variables deserving (not deserving) a detailed informative box. If C{None}, don't care. @type detailed: C{bool} """ if (self.sorted_variables is UNKNOWN or self.variable_groups is UNKNOWN): raise ValueError('sorted_variables and variable_groups ' 'must be initialized first.') if group is None: var_list = self.sorted_variables else: var_list = self.variable_groups[group] # Public/private filter (Count UNKNOWN as public) if public is True: var_list = [v for v in var_list if v.is_public is not False] elif public is False: var_list = [v for v in var_list if v.is_public is False] # Inherited filter (Count UNKNOWN as non-inherited) if inherited is None: pass elif inherited: var_list = [v for v in var_list if v.container != self] else: var_list = [v for v in var_list if v.container == self ] # Imported filter (Count UNKNOWN as non-imported) if imported is True: var_list = [v for v in var_list if v.is_imported is True] elif imported is False: var_list = [v for v in var_list if v.is_imported is not True] # Detailed filter if detailed is True: var_list = [v for v in var_list if v.is_detailed() is True] elif detailed is False: var_list = [v for v in var_list if v.is_detailed() is not True] if value_type is None: return var_list elif value_type == 'method': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, RoutineDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'instancemethod': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, RoutineDoc) and not isinstance(var_doc.value, ClassMethodDoc) and not isinstance(var_doc.value, StaticMethodDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'classmethod': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, ClassMethodDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'staticmethod': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, StaticMethodDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'property': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, PropertyDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'class': return [var_doc for var_doc in var_list if (isinstance(var_doc.value, ClassDoc) and var_doc.is_instvar in (False, UNKNOWN))] elif value_type == 'instancevariable': return [var_doc for var_doc in var_list if var_doc.is_instvar is True] elif value_type == 'classvariable': return [var_doc for var_doc in var_list if (var_doc.is_instvar in (False, UNKNOWN) and not isinstance(var_doc.value, (RoutineDoc, ClassDoc, PropertyDoc)))] else: raise ValueError('Bad value type %r' % value_type) class RoutineDoc(ValueDoc): """ API documentation information about a single routine. """ #{ Signature posargs = UNKNOWN """@ivar: The names of the routine's positional arguments. If an argument list contains \"unpacking\" arguments, then their names will be specified using nested lists. E.g., if a function's argument list is C{((x1,y1), (x2,y2))}, then posargs will be C{[['x1','y1'], ['x2','y2']]}. @type: C{list}""" posarg_defaults = UNKNOWN """@ivar: API documentation for the positional arguments' default values. This list has the same length as C{posargs}, and each element of C{posarg_defaults} describes the corresponding argument in C{posargs}. For positional arguments with no default, C{posargs_defaults} will contain None. @type: C{list} of C{ValueDoc} or C{None}""" vararg = UNKNOWN """@ivar: The name of the routine's vararg argument, or C{None} if it has no vararg argument. @type: C{string} or C{None}""" kwarg = UNKNOWN """@ivar: The name of the routine's keyword argument, or C{None} if it has no keyword argument. @type: C{string} or C{None}""" lineno = UNKNOWN # used to look up profiling info from pstats. """@ivar: The line number of the first line of the function's signature. For Python functions, this is equal to C{func.func_code.co_firstlineno}. The first line of a file is considered line 1. @type: C{int}""" #} end of "signature" group #{ Decorators decorators = UNKNOWN """@ivar: A list of names of decorators that were applied to this routine, in the order that they are listed in the source code. (I.e., in the reverse of the order that they were applied in.) @type: C{list} of C{string}""" #} end of "decorators" group #{ Information Extracted from Docstrings arg_descrs = UNKNOWN """@ivar: A list of descriptions of the routine's arguments. Each element of this list is a tuple C{(args, descr)}, where C{args} is a list of argument names; and C{descr} is a L{ParsedDocstring } describing the argument(s) specified by C{arg}. @type: C{list}""" arg_types = UNKNOWN """@ivar: Descriptions of the expected types for the routine's arguments, encoded as a dictionary mapping from argument names to type descriptions. @type: C{dict} from C{string} to L{ParsedDocstring }""" return_descr = UNKNOWN """@ivar: A description of the value returned by this routine. @type: L{ParsedDocstring}""" return_type = UNKNOWN """@ivar: A description of expected type for the value returned by this routine. @type: L{ParsedDocstring}""" exception_descrs = UNKNOWN """@ivar: A list of descriptions of exceptions that the routine might raise. Each element of this list is a tuple C{(exc, descr)}, where C{exc} is a string contianing the exception name; and C{descr} is a L{ParsedDocstring } describing the circumstances under which the exception specified by C{exc} is raised. @type: C{list}""" #} end of "information extracted from docstrings" group callgraph_uid = None """@ivar: L{DotGraph}.uid of the call graph for the function. @type: C{str}""" def is_detailed(self): if super(RoutineDoc, self).is_detailed(): return True if self.arg_descrs not in (None, UNKNOWN) and self.arg_descrs: return True if self.arg_types not in (None, UNKNOWN) and self.arg_types: return True if self.return_descr not in (None, UNKNOWN): return True if self.exception_descrs not in (None, UNKNOWN) and self.exception_descrs: return True if (self.decorators not in (None, UNKNOWN) and [ d for d in self.decorators if d not in ('classmethod', 'staticmethod') ]): return True return False def all_args(self): """ @return: A list of the names of all arguments (positional, vararg, and keyword), in order. If a positional argument consists of a tuple of names, then that tuple will be flattened. """ if self.posargs is UNKNOWN: return UNKNOWN all_args = _flatten(self.posargs) if self.vararg not in (None, UNKNOWN): all_args.append(self.vararg) if self.kwarg not in (None, UNKNOWN): all_args.append(self.kwarg) return all_args def _flatten(lst, out=None): """ Return a flattened version of C{lst}. """ if out is None: out = [] for elt in lst: if isinstance(elt, (list,tuple)): _flatten(elt, out) else: out.append(elt) return out class ClassMethodDoc(RoutineDoc): pass class StaticMethodDoc(RoutineDoc): pass class PropertyDoc(ValueDoc): """ API documentation information about a single property. """ #{ Property Access Functions fget = UNKNOWN """@ivar: API documentation for the property's get function. @type: L{RoutineDoc}""" fset = UNKNOWN """@ivar: API documentation for the property's set function. @type: L{RoutineDoc}""" fdel = UNKNOWN """@ivar: API documentation for the property's delete function. @type: L{RoutineDoc}""" #} #{ Information Extracted from Docstrings type_descr = UNKNOWN """@ivar: A description of the property's expected type, extracted from its docstring. @type: L{ParsedDocstring}""" #} end of "information extracted from docstrings" group def apidoc_links(self, **filters): val_docs = [] if self.fget not in (None, UNKNOWN): val_docs.append(self.fget) if self.fset not in (None, UNKNOWN): val_docs.append(self.fset) if self.fdel not in (None, UNKNOWN): val_docs.append(self.fdel) return val_docs def is_detailed(self): if super(PropertyDoc, self).is_detailed(): return True if self.fget not in (None, UNKNOWN) and self.fget.pyval is not None: return True if self.fset not in (None, UNKNOWN) and self.fset.pyval is not None: return True if self.fdel not in (None, UNKNOWN) and self.fdel.pyval is not None: return True return False ###################################################################### ## Index ###################################################################### class DocIndex: """ [xx] out of date. An index that .. hmm... it *can't* be used to access some things, cuz they're not at the root level. Do I want to add them or what? And if so, then I have a sort of a new top level. hmm.. so basically the question is what to do with a name that's not in the root var's name space. 2 types: - entirely outside (eg os.path) - inside but not known (eg a submodule that we didn't look at?) - container of current thing not examined? An index of all the C{APIDoc} objects that can be reached from a root set of C{ValueDoc}s. The members of this index can be accessed by dotted name. In particular, C{DocIndex} defines two mappings, accessed via the L{get_vardoc()} and L{get_valdoc()} methods, which can be used to access C{VariableDoc}s or C{ValueDoc}s respectively by name. (Two separate mappings are necessary because a single name can be used to refer to both a variable and to the value contained by that variable.) Additionally, the index defines two sets of C{ValueDoc}s: \"reachable C{ValueDoc}s\" and \"contained C{ValueDoc}s\". The X{reachable C{ValueDoc}s} are defined as the set of all C{ValueDoc}s that can be reached from the root set by following I{any} sequence of pointers to C{ValueDoc}s or C{VariableDoc}s. The X{contained C{ValueDoc}s} are defined as the set of all C{ValueDoc}s that can be reached from the root set by following only the C{ValueDoc} pointers defined by non-imported C{VariableDoc}s. For example, if the root set contains a module C{m}, then the contained C{ValueDoc}s includes the C{ValueDoc}s for any functions, variables, or classes defined in that module, as well as methods and variables defined in classes defined in the module. The reachable C{ValueDoc}s includes all of those C{ValueDoc}s, as well as C{ValueDoc}s for any values imported into the module, and base classes for classes defined in the module. """ def __init__(self, root): """ Create a new documentation index, based on the given root set of C{ValueDoc}s. If any C{APIDoc}s reachable from the root set does not have a canonical name, then it will be assigned one. etc. @param root: A list of C{ValueDoc}s. """ for apidoc in root: if apidoc.canonical_name in (None, UNKNOWN): raise ValueError("All APIdocs passed to DocIndexer " "must already have canonical names.") # Initialize the root items list. We sort them by length in # ascending order. (This ensures that variables will shadow # submodules when appropriate.) # When the elements name is the same, list in alphabetical order: # this is needed by the check for duplicates below. self.root = sorted(root, key=lambda d: (len(d.canonical_name), d.canonical_name)) """The list of C{ValueDoc}s to document. @type: C{list}""" # Drop duplicated modules # [xx] maybe what causes duplicates should be fixed instead. # If fixed, adjust the sort here above: sorting by names will not # be required anymore i = 1 while i < len(self.root): if self.root[i-1] is self.root[i]: del self.root[i] else: i += 1 self.mlclasses = self._get_module_classes(self.root) """A mapping from class names to L{ClassDoc}. Contains classes defined at module level for modules in L{root} and which can be used as fallback by L{find()} if looking in containing namespaces fails. @type: C{dict} from C{str} to L{ClassDoc} or C{list}""" self.callers = None """A dictionary mapping from C{RoutineDoc}s in this index to lists of C{RoutineDoc}s for the routine's callers. This dictionary is initialized by calling L{read_profiling_info()}. @type: C{list} of L{RoutineDoc}""" self.callees = None """A dictionary mapping from C{RoutineDoc}s in this index to lists of C{RoutineDoc}s for the routine's callees. This dictionary is initialized by calling L{read_profiling_info()}. @type: C{list} of L{RoutineDoc}""" self._funcid_to_doc = {} """A mapping from C{profile} function ids to corresponding C{APIDoc} objects. A function id is a tuple of the form C{(filename, lineno, funcname)}. This is used to update the L{callers} and L{callees} variables.""" self._container_cache = {} """A cache for the L{container()} method, to increase speed.""" self._get_cache = {} """A cache for the L{get_vardoc()} and L{get_valdoc()} methods, to increase speed.""" #//////////////////////////////////////////////////////////// # Lookup methods #//////////////////////////////////////////////////////////// # [xx] # Currently these only work for things reachable from the # root... :-/ I might want to change this so that imported # values can be accessed even if they're not contained. # Also, I might want canonical names to not start with ?? # if the thing is a top-level imported module..? def get_vardoc(self, name): """ Return the C{VariableDoc} with the given name, or C{None} if this index does not contain a C{VariableDoc} with the given name. """ var, val = self._get(name) return var def get_valdoc(self, name): """ Return the C{ValueDoc} with the given name, or C{None} if this index does not contain a C{ValueDoc} with the given name. """ var, val = self._get(name) return val def _get(self, name): """ A helper function that's used to implement L{get_vardoc()} and L{get_valdoc()}. """ # Convert name to a DottedName, if necessary. if not isinstance(name, DottedName): name = DottedName(name) # Check if the result is cached. val = self._get_cache.get(name) if val is not None: return val # Look for an element in the root set whose name is a prefix # of `name`. If we can't find one, then return None. for root_valdoc in self.root: if root_valdoc.canonical_name.dominates(name): # Starting at the root valdoc, walk down the variable/ # submodule chain until we find the requested item. var_doc = None val_doc = root_valdoc for identifier in name[len(root_valdoc.canonical_name):]: if val_doc is None: break var_doc, val_doc = self._get_from(val_doc, identifier) else: # If we found it, then return. if var_doc is not None or val_doc is not None: self._get_cache[name] = (var_doc, val_doc) return var_doc, val_doc # We didn't find it. self._get_cache[name] = (None, None) return None, None def _get_from(self, val_doc, identifier): if isinstance(val_doc, NamespaceDoc): child_var = val_doc.variables.get(identifier) if child_var is not None: child_val = child_var.value if child_val is UNKNOWN: child_val = None return child_var, child_val # If that fails, then see if it's a submodule. if (isinstance(val_doc, ModuleDoc) and val_doc.submodules is not UNKNOWN): for submodule in val_doc.submodules: if submodule.canonical_name[-1] == identifier: var_doc = None val_doc = submodule if val_doc is UNKNOWN: val_doc = None return var_doc, val_doc return None, None def find(self, name, context): """ Look for an C{APIDoc} named C{name}, relative to C{context}. Return the C{APIDoc} if one is found; otherwise, return C{None}. C{find} looks in the following places, in order: - Function parameters (if one matches, return C{None}) - All enclosing namespaces, from closest to furthest. - If C{name} starts with C{'self'}, then strip it off and look for the remaining part of the name using C{find} - Builtins - Parameter attributes - Classes at module level (if the name is not ambiguous) @type name: C{str} or L{DottedName} @type context: L{APIDoc} """ if isinstance(name, basestring): name = re.sub(r'\(.*\)$', '', name.strip()) if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name): name = DottedName(name) else: return None elif not isinstance(name, DottedName): raise TypeError("'name' should be a string or DottedName") if context is None or context.canonical_name is None: container_name = [] else: container_name = context.canonical_name # Check for the name in all containing namespaces, starting # with the closest one. for i in range(len(container_name), -1, -1): relative_name = container_name[:i]+name # Is `name` the absolute name of a documented value? # (excepting GenericValueDoc values.) val_doc = self.get_valdoc(relative_name) if (val_doc is not None and not isinstance(val_doc, GenericValueDoc)): return val_doc # Is `name` the absolute name of a documented variable? var_doc = self.get_vardoc(relative_name) if var_doc is not None: return var_doc # If the name begins with 'self', then try stripping that off # and see if we can find the variable. if name[0] == 'self': doc = self.find('.'.join(name[1:]), context) if doc is not None: return doc # Is it the name of a builtin? if len(name)==1 and hasattr(__builtin__, name[0]): return None # Is it a parameter's name or an attribute of a parameter? if isinstance(context, RoutineDoc): all_args = context.all_args() if all_args is not UNKNOWN and name[0] in all_args: return None # Is this an object directly contained by any module? doc = self.mlclasses.get(name[-1]) if isinstance(doc, APIDoc): return doc elif isinstance(doc, list): log.warning("%s is an ambiguous name: it may be %s" % ( name[-1], ", ".join([ "'%s'" % d.canonical_name for d in doc ]))) # Drop this item so that the warning is reported only once. # fail() will fail anyway. del self.mlclasses[name[-1]] def _get_module_classes(self, docs): """ Gather all the classes defined in a list of modules. Very often people refers to classes only by class name, even if they are not imported in the namespace. Linking to such classes will fail if we look for them only in nested namespaces. Allow them to retrieve only by name. @param docs: containers of the objects to collect @type docs: C{list} of C{APIDoc} @return: mapping from objects name to the object(s) with that name @rtype: C{dict} from C{str} to L{ClassDoc} or C{list} """ classes = {} for doc in docs: if not isinstance(doc, ModuleDoc): continue for var in doc.variables.values(): if not isinstance(var.value, ClassDoc): continue val = var.value if val in (None, UNKNOWN) or val.defining_module is not doc: continue if val.canonical_name in (None, UNKNOWN): continue name = val.canonical_name[-1] vals = classes.get(name) if vals is None: classes[name] = val elif not isinstance(vals, list): classes[name] = [ vals, val ] else: vals.append(val) return classes #//////////////////////////////////////////////////////////// # etc #//////////////////////////////////////////////////////////// def reachable_valdocs(self, **filters): """ Return a list of all C{ValueDoc}s that can be reached, directly or indirectly from this C{DocIndex}'s root set. @param filters: A set of filters that can be used to prevent C{reachable_valdocs} from following specific link types when looking for C{ValueDoc}s that can be reached from the root set. See C{APIDoc.apidoc_links} for a more complete description. """ return reachable_valdocs(self.root, **filters) def container(self, api_doc): """ Return the C{ValueDoc} that contains the given C{APIDoc}, or C{None} if its container is not in the index. """ # Check if the result is cached. val = self._container_cache.get(api_doc) if val is not None: return val if isinstance(api_doc, GenericValueDoc): self._container_cache[api_doc] = None return None # [xx] unknown. if isinstance(api_doc, VariableDoc): self._container_cache[api_doc] = api_doc.container return api_doc.container if len(api_doc.canonical_name) == 1: self._container_cache[api_doc] = None return None elif isinstance(api_doc, ModuleDoc) and api_doc.package is not UNKNOWN: self._container_cache[api_doc] = api_doc.package return api_doc.package else: parent = self.get_valdoc(api_doc.canonical_name.container()) self._container_cache[api_doc] = parent return parent #//////////////////////////////////////////////////////////// # Profiling information #//////////////////////////////////////////////////////////// def read_profiling_info(self, profile_stats): """ Initialize the L{callers} and L{callees} variables, given a C{Stat} object from the C{pstats} module. @warning: This method uses undocumented data structures inside of C{profile_stats}. """ if self.callers is None: self.callers = {} if self.callees is None: self.callees = {} # The Stat object encodes functions using `funcid`s, or # tuples of (filename, lineno, funcname). Create a mapping # from these `funcid`s to `RoutineDoc`s. self._update_funcid_to_doc(profile_stats) for callee, (cc, nc, tt, ct, callers) in profile_stats.stats.items(): callee = self._funcid_to_doc.get(callee) if callee is None: continue for caller in callers: caller = self._funcid_to_doc.get(caller) if caller is None: continue self.callers.setdefault(callee, []).append(caller) self.callees.setdefault(caller, []).append(callee) def _update_funcid_to_doc(self, profile_stats): """ Update the dictionary mapping from C{pstat.Stat} funciton ids to C{RoutineDoc}s. C{pstat.Stat} function ids are tuples of C{(filename, lineno, funcname)}. """ # Maps (filename, lineno, funcname) -> RoutineDoc for val_doc in self.reachable_valdocs(): # We only care about routines. if not isinstance(val_doc, RoutineDoc): continue # Get the filename from the defining module. module = val_doc.defining_module if module is UNKNOWN or module.filename is UNKNOWN: continue # Normalize the filename. filename = os.path.abspath(module.filename) try: filename = py_src_filename(filename) except: pass # Look up the stat_func_id funcid = (filename, val_doc.lineno, val_doc.canonical_name[-1]) if funcid in profile_stats.stats: self._funcid_to_doc[funcid] = val_doc ###################################################################### ## Pretty Printing ###################################################################### def pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(), backpointers=None): """ @return: A multiline pretty-printed string representation for the given C{APIDoc}. @param doublespace: If true, then extra lines will be inserted to make the output more readable. @param depth: The maximum depth that pp_apidoc will descend into descendent VarDocs. To put no limit on depth, use C{depth=-1}. @param exclude: A list of names of attributes whose values should not be shown. @param backpointers: For internal use. """ pyid = id(api_doc.__dict__) if backpointers is None: backpointers = {} if (hasattr(api_doc, 'canonical_name') and api_doc.canonical_name not in (None, UNKNOWN)): name = '%s for %s' % (api_doc.__class__.__name__, api_doc.canonical_name) elif getattr(api_doc, 'name', None) not in (UNKNOWN, None): if (getattr(api_doc, 'container', None) not in (UNKNOWN, None) and getattr(api_doc.container, 'canonical_name', None) not in (UNKNOWN, None)): name ='%s for %s' % (api_doc.__class__.__name__, api_doc.container.canonical_name+ api_doc.name) else: name = '%s for %s' % (api_doc.__class__.__name__, api_doc.name) else: name = api_doc.__class__.__name__ if pyid in backpointers: return '%s [%s] (defined above)' % (name, backpointers[pyid]) if depth == 0: if hasattr(api_doc, 'name') and api_doc.name is not None: return '%s...' % api_doc.name else: return '...' backpointers[pyid] = len(backpointers) s = '%s [%s]' % (name, backpointers[pyid]) # Only print non-empty fields: fields = [field for field in api_doc.__dict__.keys() if (field in include or (getattr(api_doc, field) is not UNKNOWN and field not in exclude))] if include: fields = [field for field in dir(api_doc) if field in include] else: fields = [field for field in api_doc.__dict__.keys() if (getattr(api_doc, field) is not UNKNOWN and field not in exclude)] fields.sort() for field in fields: fieldval = getattr(api_doc, field) if doublespace: s += '\n |' s += '\n +- %s' % field if (isinstance(fieldval, types.ListType) and len(fieldval)>0 and isinstance(fieldval[0], APIDoc)): s += _pp_list(api_doc, fieldval, doublespace, depth, exclude, include, backpointers, (field is fields[-1])) elif (isinstance(fieldval, types.DictType) and len(fieldval)>0 and isinstance(fieldval.values()[0], APIDoc)): s += _pp_dict(api_doc, fieldval, doublespace, depth, exclude, include, backpointers, (field is fields[-1])) elif isinstance(fieldval, APIDoc): s += _pp_apidoc(api_doc, fieldval, doublespace, depth, exclude, include, backpointers, (field is fields[-1])) else: s += ' = ' + _pp_val(api_doc, fieldval, doublespace, depth, exclude, include, backpointers) return s def _pp_list(api_doc, items, doublespace, depth, exclude, include, backpointers, is_last): line1 = (is_last and ' ') or '|' s = '' for item in items: line2 = ((item is items[-1]) and ' ') or '|' joiner = '\n %s %s ' % (line1, line2) if doublespace: s += '\n %s |' % line1 s += '\n %s +- ' % line1 valstr = _pp_val(api_doc, item, doublespace, depth, exclude, include, backpointers) s += joiner.join(valstr.split('\n')) return s def _pp_dict(api_doc, dict, doublespace, depth, exclude, include, backpointers, is_last): items = dict.items() items.sort() line1 = (is_last and ' ') or '|' s = '' for item in items: line2 = ((item is items[-1]) and ' ') or '|' joiner = '\n %s %s ' % (line1, line2) if doublespace: s += '\n %s |' % line1 s += '\n %s +- ' % line1 valstr = _pp_val(api_doc, item[1], doublespace, depth, exclude, include, backpointers) s += joiner.join(('%s => %s' % (item[0], valstr)).split('\n')) return s def _pp_apidoc(api_doc, val, doublespace, depth, exclude, include, backpointers, is_last): line1 = (is_last and ' ') or '|' s = '' if doublespace: s += '\n %s | ' % line1 s += '\n %s +- ' % line1 joiner = '\n %s ' % line1 childstr = pp_apidoc(val, doublespace, depth-1, exclude, include, backpointers) return s + joiner.join(childstr.split('\n')) def _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers): from epydoc import markup if isinstance(val, APIDoc): return pp_apidoc(val, doublespace, depth-1, exclude, include, backpointers) elif isinstance(val, markup.ParsedDocstring): valrepr = `val.to_plaintext(None)` if len(valrepr) < 40: return valrepr else: return valrepr[:37]+'...' else: valrepr = repr(val) if len(valrepr) < 40: return valrepr else: return valrepr[:37]+'...' epydoc-3.0.1+dfsg/epydoc/docbuilder.py0000644000175000017500000016073210747666675020207 0ustar pronovicpronovic# epydoc -- Documentation Builder # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: docbuilder.py 1683 2008-01-29 22:17:39Z edloper $ """ Construct data structures that encode the API documentation for Python objects. These data structures are created using a series of steps: 1. B{Building docs}: Extract basic information about the objects, and objects that are related to them. This can be done by introspecting the objects' values (with L{epydoc.docintrospecter}; or by parsing their source code (with L{epydoc.docparser}. 2. B{Merging}: Combine the information obtained from introspection & parsing each object into a single structure. 3. B{Linking}: Replace any 'pointers' that were created for imported variables by their target (if it's available). 4. B{Naming}: Chose a unique 'canonical name' for each object. 5. B{Docstring Parsing}: Parse the docstring of each object, and extract any pertinant information. 6. B{Inheritance}: Add information about variables that classes inherit from their base classes. The documentation information for each individual object is represented using an L{APIDoc}; and the documentation for a collection of objects is represented using a L{DocIndex}. The main interface to C{epydoc.docbuilder} consists of two functions: - L{build_doc()} -- Builds documentation for a single item, and returns it as an L{APIDoc} object. - L{build_doc_index()} -- Builds documentation for a collection of items, and returns it as a L{DocIndex} object. The remaining functions are used by these two main functions to perform individual steps in the creation of the documentation. @group Documentation Construction: build_doc, build_doc_index, _get_docs_from_*, _report_valdoc_progress @group Merging: *MERGE*, *merge* @group Linking: link_imports @group Naming: _name_scores, _unreachable_names, assign_canonical_names, _var_shadows_self, _fix_self_shadowing_var, _unreachable_name_for @group Inheritance: inherit_docs, _inherit_info """ __docformat__ = 'epytext en' ###################################################################### ## Contents ###################################################################### ## 1. build_doc() & build_doc_index() -- the main interface. ## 2. merge_docs() -- helper, used to merge parse & introspect info ## 3. link_imports() -- helper, used to connect imported vars w/ values ## 4. assign_canonical_names() -- helper, used to set canonical names ## 5. inherit_docs() -- helper, used to inherit docs from base classes ###################################################################### ## Imports ###################################################################### import sys, os, os.path, __builtin__, imp, re, inspect from epydoc.apidoc import * from epydoc.docintrospecter import introspect_docs from epydoc.docparser import parse_docs, ParseError from epydoc.docstringparser import parse_docstring from epydoc import log from epydoc.util import * from epydoc.compat import * # Backwards compatibility ###################################################################### ## 1. build_doc() ###################################################################### class BuildOptions: """ Holds the parameters for a documentation building process. """ def __init__(self, introspect=True, parse=True, exclude_introspect=None, exclude_parse=None, add_submodules=True): self.introspect = introspect self.parse = parse self.exclude_introspect = exclude_introspect self.exclude_parse = exclude_parse self.add_submodules = add_submodules # Test for pattern syntax and compile them into pattern objects. try: self._introspect_regexp = (exclude_introspect and re.compile(exclude_introspect) or None) self._parse_regexp = (exclude_parse and re.compile(exclude_parse) or None) except Exception, exc: log.error('Error in regular expression pattern: %s' % exc) raise def must_introspect(self, name): """ Return C{True} if a module is to be introsepcted with the current settings. @param name: The name of the module to test @type name: L{DottedName} or C{str} """ return self.introspect \ and not self._matches_filter(name, self._introspect_regexp) def must_parse(self, name): """ Return C{True} if a module is to be parsed with the current settings. @param name: The name of the module to test @type name: L{DottedName} or C{str} """ return self.parse \ and not self._matches_filter(name, self._parse_regexp) def _matches_filter(self, name, regexp): """ Test if a module name matches a pattern. @param name: The name of the module to test @type name: L{DottedName} or C{str} @param regexp: The pattern object to match C{name} against. If C{None}, return C{False} @type regexp: C{pattern} @return: C{True} if C{name} in dotted format matches C{regexp}, else C{False} @rtype: C{bool} """ if regexp is None: return False if isinstance(name, DottedName): name = str(name) return bool(regexp.search(name)) def build_doc(item, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None): """ Build API documentation for a given item, and return it as an L{APIDoc} object. @rtype: L{APIDoc} @param item: The item to document, specified using any of the following: - A string, naming a python package directory (e.g., C{'epydoc/markup'}) - A string, naming a python file (e.g., C{'epydoc/docparser.py'}) - A string, naming a python object (e.g., C{'epydoc.docparser.DocParser'}) - Any (non-string) python object (e.g., C{list.append}) @param introspect: If true, then use introspection to examine the specified items. Otherwise, just use parsing. @param parse: If true, then use parsing to examine the specified items. Otherwise, just use introspection. """ docindex = build_doc_index([item], introspect, parse, add_submodules, exclude_introspect=exclude_introspect, exclude_parse=exclude_parse) return docindex.root[0] def build_doc_index(items, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None): """ Build API documentation for the given list of items, and return it in the form of a L{DocIndex}. @rtype: L{DocIndex} @param items: The items to document, specified using any of the following: - A string, naming a python package directory (e.g., C{'epydoc/markup'}) - A string, naming a python file (e.g., C{'epydoc/docparser.py'}) - A string, naming a python object (e.g., C{'epydoc.docparser.DocParser'}) - Any (non-string) python object (e.g., C{list.append}) @param introspect: If true, then use introspection to examine the specified items. Otherwise, just use parsing. @param parse: If true, then use parsing to examine the specified items. Otherwise, just use introspection. """ try: options = BuildOptions(parse=parse, introspect=introspect, exclude_introspect=exclude_introspect, exclude_parse=exclude_parse, add_submodules=add_submodules) except Exception, e: # log.error already reported by constructor. return None # Get the basic docs for each item. doc_pairs = _get_docs_from_items(items, options) # Merge the introspection & parse docs. if options.parse and options.introspect: log.start_progress('Merging parsed & introspected information') docs = [] for i, (introspect_doc, parse_doc) in enumerate(doc_pairs): if introspect_doc is not None and parse_doc is not None: if introspect_doc.canonical_name not in (None, UNKNOWN): name = introspect_doc.canonical_name else: name = parse_doc.canonical_name log.progress(float(i)/len(doc_pairs), name) docs.append(merge_docs(introspect_doc, parse_doc)) elif introspect_doc is not None: docs.append(introspect_doc) elif parse_doc is not None: docs.append(parse_doc) log.end_progress() elif options.introspect: docs = [doc_pair[0] for doc_pair in doc_pairs if doc_pair[0]] else: docs = [doc_pair[1] for doc_pair in doc_pairs if doc_pair[1]] if len(docs) == 0: log.error('Nothing left to document!') return None # Collect the docs into a single index. docindex = DocIndex(docs) # Replace any proxy valuedocs that we got from importing with # their targets. if options.parse: log.start_progress('Linking imported variables') valdocs = sorted(docindex.reachable_valdocs( imports=False, submodules=False, packages=False, subclasses=False)) for i, val_doc in enumerate(valdocs): _report_valdoc_progress(i, val_doc, valdocs) link_imports(val_doc, docindex) log.end_progress() # Assign canonical names. log.start_progress('Indexing documentation') for i, val_doc in enumerate(docindex.root): log.progress(float(i)/len(docindex.root), val_doc.canonical_name) assign_canonical_names(val_doc, val_doc.canonical_name, docindex) log.end_progress() # Set overrides pointers log.start_progress('Checking for overridden methods') valdocs = sorted(docindex.reachable_valdocs( imports=False, submodules=False, packages=False, subclasses=False)) for i, val_doc in enumerate(valdocs): if isinstance(val_doc, ClassDoc): percent = float(i)/len(valdocs) log.progress(percent, val_doc.canonical_name) find_overrides(val_doc) log.end_progress() # Parse the docstrings for each object. log.start_progress('Parsing docstrings') suppress_warnings = set(valdocs).difference( docindex.reachable_valdocs( imports=False, submodules=False, packages=False, subclasses=False, bases=False, overrides=True)) for i, val_doc in enumerate(valdocs): _report_valdoc_progress(i, val_doc, valdocs) # the value's docstring parse_docstring(val_doc, docindex, suppress_warnings) # the value's variables' docstrings if (isinstance(val_doc, NamespaceDoc) and val_doc.variables not in (None, UNKNOWN)): for var_doc in val_doc.variables.values(): # Now we have a chance to propagate the defining module # to objects for which introspection is not possible, # such as properties. if (isinstance(var_doc.value, ValueDoc) and var_doc.value.defining_module is UNKNOWN): var_doc.value.defining_module = val_doc.defining_module parse_docstring(var_doc, docindex, suppress_warnings) log.end_progress() # Take care of inheritance. log.start_progress('Inheriting documentation') for i, val_doc in enumerate(valdocs): if isinstance(val_doc, ClassDoc): percent = float(i)/len(valdocs) log.progress(percent, val_doc.canonical_name) inherit_docs(val_doc) log.end_progress() # Initialize the groups & sortedvars attributes. log.start_progress('Sorting & Grouping') for i, val_doc in enumerate(valdocs): if isinstance(val_doc, NamespaceDoc): percent = float(i)/len(valdocs) log.progress(percent, val_doc.canonical_name) val_doc.init_sorted_variables() val_doc.init_variable_groups() if isinstance(val_doc, ModuleDoc): val_doc.init_submodule_groups() val_doc.report_unused_groups() log.end_progress() return docindex def _report_valdoc_progress(i, val_doc, val_docs): if (isinstance(val_doc, (ModuleDoc, ClassDoc)) and val_doc.canonical_name is not UNKNOWN and not val_doc.canonical_name[0].startswith('??')): log.progress(float(i)/len(val_docs), val_doc.canonical_name) #///////////////////////////////////////////////////////////////// # Documentation Generation #///////////////////////////////////////////////////////////////// def _get_docs_from_items(items, options): # Start the progress bar. log.start_progress('Building documentation') progress_estimator = _ProgressEstimator(items) # Check for duplicate item names. item_set = set() for item in items[:]: if item in item_set: log.warning("Name %r given multiple times" % item) items.remove(item) item_set.add(item) # Keep track of what top-level canonical names we've assigned, to # make sure there are no naming conflicts. This dict maps # canonical names to the item names they came from (so we can print # useful error messages). canonical_names = {} # Collect (introspectdoc, parsedoc) pairs for each item. doc_pairs = [] for item in items: if isinstance(item, basestring): if is_module_file(item): doc_pairs.append(_get_docs_from_module_file( item, options, progress_estimator)) elif is_package_dir(item): pkgfile = os.path.abspath(os.path.join(item, '__init__')) doc_pairs.append(_get_docs_from_module_file( pkgfile, options, progress_estimator)) elif os.path.isfile(item): doc_pairs.append(_get_docs_from_pyscript( item, options, progress_estimator)) elif hasattr(__builtin__, item): val = getattr(__builtin__, item) doc_pairs.append(_get_docs_from_pyobject( val, options, progress_estimator)) elif is_pyname(item): doc_pairs.append(_get_docs_from_pyname( item, options, progress_estimator)) elif os.path.isdir(item): log.error("Directory %r is not a package" % item) continue elif os.path.isfile(item): log.error("File %s is not a Python module" % item) continue else: log.error("Could not find a file or object named %s" % item) continue else: doc_pairs.append(_get_docs_from_pyobject( item, options, progress_estimator)) # Make sure there are no naming conflicts. name = (getattr(doc_pairs[-1][0], 'canonical_name', None) or getattr(doc_pairs[-1][1], 'canonical_name', None)) if name in canonical_names: log.error( 'Two of the specified items, %r and %r, have the same ' 'canonical name ("%s"). This may mean that you specified ' 'two different files that both use the same module name. ' 'Ignoring the second item (%r)' % (canonical_names[name], item, name, canonical_names[name])) doc_pairs.pop() else: canonical_names[name] = item # This will only have an effect if doc_pairs[-1] contains a # package's docs. The 'not is_module_file(item)' prevents # us from adding subdirectories if they explicitly specify # a package's __init__.py file. if options.add_submodules and not is_module_file(item): doc_pairs += _get_docs_from_submodules( item, doc_pairs[-1], options, progress_estimator) log.end_progress() return doc_pairs def _get_docs_from_pyobject(obj, options, progress_estimator): progress_estimator.complete += 1 log.progress(progress_estimator.progress(), repr(obj)) if not options.introspect: log.error("Cannot get docs for Python objects without " "introspecting them.") introspect_doc = parse_doc = None introspect_error = parse_error = None try: introspect_doc = introspect_docs(value=obj) except ImportError, e: log.error(e) return (None, None) if options.parse: if introspect_doc.canonical_name is not None: prev_introspect = options.introspect options.introspect = False try: _, parse_docs = _get_docs_from_pyname( str(introspect_doc.canonical_name), options, progress_estimator, suppress_warnings=True) finally: options.introspect = prev_introspect # We need a name: if introspect_doc.canonical_name in (None, UNKNOWN): if hasattr(obj, '__name__'): introspect_doc.canonical_name = DottedName( DottedName.UNREACHABLE, obj.__name__) else: introspect_doc.canonical_name = DottedName( DottedName.UNREACHABLE) return (introspect_doc, parse_doc) def _get_docs_from_pyname(name, options, progress_estimator, suppress_warnings=False): progress_estimator.complete += 1 if options.must_introspect(name) or options.must_parse(name): log.progress(progress_estimator.progress(), name) introspect_doc = parse_doc = None introspect_error = parse_error = None if options.must_introspect(name): try: introspect_doc = introspect_docs(name=name) except ImportError, e: introspect_error = str(e) if options.must_parse(name): try: parse_doc = parse_docs(name=name) except ParseError, e: parse_error = str(e) except ImportError, e: # If we get here, then there' probably no python source # available; don't bother to generate a warnining. pass # Report any errors we encountered. if not suppress_warnings: _report_errors(name, introspect_doc, parse_doc, introspect_error, parse_error) # Return the docs we found. return (introspect_doc, parse_doc) def _get_docs_from_pyscript(filename, options, progress_estimator): # [xx] I should be careful about what names I allow as filenames, # and maybe do some munging to prevent problems. introspect_doc = parse_doc = None introspect_error = parse_error = None if options.introspect: try: introspect_doc = introspect_docs(filename=filename, is_script=True) if introspect_doc.canonical_name is UNKNOWN: introspect_doc.canonical_name = munge_script_name(filename) except ImportError, e: introspect_error = str(e) if options.parse: try: parse_doc = parse_docs(filename=filename, is_script=True) except ParseError, e: parse_error = str(e) except ImportError, e: parse_error = str(e) # Report any errors we encountered. _report_errors(filename, introspect_doc, parse_doc, introspect_error, parse_error) # Return the docs we found. return (introspect_doc, parse_doc) def _get_docs_from_module_file(filename, options, progress_estimator, parent_docs=(None,None)): """ Construct and return the API documentation for the python module with the given filename. @param parent_docs: The C{ModuleDoc} of the containing package. If C{parent_docs} is not provided, then this method will check if the given filename is contained in a package; and if so, it will construct a stub C{ModuleDoc} for the containing package(s). C{parent_docs} is a tuple, where the first element is the parent from introspection, and the second element is the parent from parsing. """ # Record our progress. modulename = os.path.splitext(os.path.split(filename)[1])[0] if modulename == '__init__': modulename = os.path.split(os.path.split(filename)[0])[1] if parent_docs[0]: modulename = DottedName(parent_docs[0].canonical_name, modulename) elif parent_docs[1]: modulename = DottedName(parent_docs[1].canonical_name, modulename) if options.must_introspect(modulename) or options.must_parse(modulename): log.progress(progress_estimator.progress(), '%s (%s)' % (modulename, filename)) progress_estimator.complete += 1 # Normalize the filename. filename = os.path.normpath(os.path.abspath(filename)) # When possible, use the source version of the file. try: filename = py_src_filename(filename) src_file_available = True except ValueError: src_file_available = False # Get the introspected & parsed docs (as appropriate) introspect_doc = parse_doc = None introspect_error = parse_error = None if options.must_introspect(modulename): try: introspect_doc = introspect_docs( filename=filename, context=parent_docs[0]) if introspect_doc.canonical_name is UNKNOWN: introspect_doc.canonical_name = modulename except ImportError, e: introspect_error = str(e) if src_file_available and options.must_parse(modulename): try: parse_doc = parse_docs( filename=filename, context=parent_docs[1]) except ParseError, e: parse_error = str(e) except ImportError, e: parse_error = str(e) # Report any errors we encountered. _report_errors(filename, introspect_doc, parse_doc, introspect_error, parse_error) # Return the docs we found. return (introspect_doc, parse_doc) def _get_docs_from_submodules(item, pkg_docs, options, progress_estimator): # Extract the package's __path__. if isinstance(pkg_docs[0], ModuleDoc) and pkg_docs[0].is_package: pkg_path = pkg_docs[0].path package_dir = os.path.split(pkg_docs[0].filename)[0] elif isinstance(pkg_docs[1], ModuleDoc) and pkg_docs[1].is_package: pkg_path = pkg_docs[1].path package_dir = os.path.split(pkg_docs[1].filename)[0] else: return [] module_filenames = {} subpackage_dirs = set() for subdir in pkg_path: if os.path.isdir(subdir): for name in os.listdir(subdir): filename = os.path.join(subdir, name) # Is it a valid module filename? if is_module_file(filename): basename = os.path.splitext(filename)[0] if os.path.split(basename)[1] != '__init__': module_filenames[basename] = filename # Is it a valid package filename? if is_package_dir(filename): subpackage_dirs.add(filename) # Update our estimate of the number of modules in this package. progress_estimator.revise_estimate(item, module_filenames.items(), subpackage_dirs) docs = [pkg_docs] for module_filename in module_filenames.values(): d = _get_docs_from_module_file( module_filename, options, progress_estimator, pkg_docs) docs.append(d) for subpackage_dir in subpackage_dirs: subpackage_file = os.path.join(subpackage_dir, '__init__') docs.append(_get_docs_from_module_file( subpackage_file, options, progress_estimator, pkg_docs)) docs += _get_docs_from_submodules( subpackage_dir, docs[-1], options, progress_estimator) return docs def _report_errors(name, introspect_doc, parse_doc, introspect_error, parse_error): hdr = 'In %s:\n' % name if introspect_doc == parse_doc == None: log.start_block('%sNo documentation available!' % hdr) if introspect_error: log.error('Import failed:\n%s' % introspect_error) if parse_error: log.error('Source code parsing failed:\n%s' % parse_error) log.end_block() elif introspect_error: log.start_block('%sImport failed (but source code parsing ' 'was successful).' % hdr) log.error(introspect_error) log.end_block() elif parse_error: log.start_block('%sSource code parsing failed (but ' 'introspection was successful).' % hdr) log.error(parse_error) log.end_block() #///////////////////////////////////////////////////////////////// # Progress Estimation (for Documentation Generation) #///////////////////////////////////////////////////////////////// class _ProgressEstimator: """ Used to keep track of progress when generating the initial docs for the given items. (It is not known in advance how many items a package directory will contain, since it might depend on those packages' __path__ values.) """ def __init__(self, items): self.est_totals = {} self.complete = 0 for item in items: if is_package_dir(item): self.est_totals[item] = self._est_pkg_modules(item) else: self.est_totals[item] = 1 def progress(self): total = sum(self.est_totals.values()) return float(self.complete) / total def revise_estimate(self, pkg_item, modules, subpackages): del self.est_totals[pkg_item] for item in modules: self.est_totals[item] = 1 for item in subpackages: self.est_totals[item] = self._est_pkg_modules(item) def _est_pkg_modules(self, package_dir): num_items = 0 if is_package_dir(package_dir): for name in os.listdir(package_dir): filename = os.path.join(package_dir, name) if is_module_file(filename): num_items += 1 elif is_package_dir(filename): num_items += self._est_pkg_modules(filename) return num_items ###################################################################### ## Doc Merger ###################################################################### MERGE_PRECEDENCE = { 'repr': 'parse', # The names we get from introspection match the names that users # can actually use -- i.e., they take magic into account. 'canonical_name': 'introspect', # Only fall-back on the parser for is_imported if the introspecter # isn't sure. Otherwise, we can end up thinking that vars # containing modules are not imported, which can cause external # modules to show up in the docs (sf bug #1653486) 'is_imported': 'introspect', # The parser can tell if an assignment creates an alias or not. 'is_alias': 'parse', # The parser is better able to determine what text file something # came from; e.g., it can't be fooled by 'covert' imports. 'docformat': 'parse', # The parse should be able to tell definitively whether a module # is a package or not. 'is_package': 'parse', # Extract the sort spec from the order in which values are defined # in the source file. 'sort_spec': 'parse', 'submodules': 'introspect', # The filename used by 'parse' is the source file. 'filename': 'parse', # 'parse' is more likely to get the encoding right, but # 'introspect' will handle programatically generated docstrings. # Which is better? 'docstring': 'introspect', } """Indicates whether information from introspection or parsing should be given precedence, for specific attributes. This dictionary maps from attribute names to either C{'introspect'} or C{'parse'}.""" DEFAULT_MERGE_PRECEDENCE = 'introspect' """Indicates whether information from introspection or parsing should be given precedence. Should be either C{'introspect'} or C{'parse'}""" _attribute_mergefunc_registry = {} def register_attribute_mergefunc(attrib, mergefunc): """ Register an attribute merge function. This function will be called by L{merge_docs()} when it needs to merge the attribute values of two C{APIDoc}s. @param attrib: The name of the attribute whose values are merged by C{mergefunc}. @param mergefunc: The merge function, whose sinature is: >>> def mergefunc(introspect_val, parse_val, precedence, cyclecheck, path): ... return calculate_merged_value(introspect_val, parse_val) Where C{introspect_val} and C{parse_val} are the two values to combine; C{precedence} is a string indicating which value takes precedence for this attribute (C{'introspect'} or C{'parse'}); C{cyclecheck} is a value used by C{merge_docs()} to make sure that it only visits each pair of docs once; and C{path} is a string describing the path that was taken from the root to this attribute (used to generate log messages). If the merge function needs to call C{merge_docs}, then it should pass C{cyclecheck} and C{path} back in. (When appropriate, a suffix should be added to C{path} to describe the path taken to the merged values.) """ _attribute_mergefunc_registry[attrib] = mergefunc def merge_docs(introspect_doc, parse_doc, cyclecheck=None, path=None): """ Merge the API documentation information that was obtained from introspection with information that was obtained from parsing. C{introspect_doc} and C{parse_doc} should be two C{APIDoc} instances that describe the same object. C{merge_docs} combines the information from these two instances, and returns the merged C{APIDoc}. If C{introspect_doc} and C{parse_doc} are compatible, then they will be I{merged} -- i.e., they will be coerced to a common class, and their state will be stored in a shared dictionary. Once they have been merged, any change made to the attributes of one will affect the other. The value for the each of the merged C{APIDoc}'s attributes is formed by combining the values of the source C{APIDoc}s' attributes, as follows: - If either of the source attributes' value is C{UNKNOWN}, then use the other source attribute's value. - Otherwise, if an attribute merge function has been registered for the attribute, then use that function to calculate the merged value from the two source attribute values. - Otherwise, if L{MERGE_PRECEDENCE} is defined for the attribute, then use the attribute value from the source that it indicates. - Otherwise, use the attribute value from the source indicated by L{DEFAULT_MERGE_PRECEDENCE}. If C{introspect_doc} and C{parse_doc} are I{not} compatible (e.g., if their values have incompatible types), then C{merge_docs()} will simply return either C{introspect_doc} or C{parse_doc}, depending on the value of L{DEFAULT_MERGE_PRECEDENCE}. The two input C{APIDoc}s will not be merged or modified in any way. @param cyclecheck, path: These arguments should only be provided when C{merge_docs()} is called by an attribute merge function. See L{register_attribute_mergefunc()} for more details. """ assert isinstance(introspect_doc, APIDoc) assert isinstance(parse_doc, APIDoc) if cyclecheck is None: cyclecheck = set() if introspect_doc.canonical_name not in (None, UNKNOWN): path = '%s' % introspect_doc.canonical_name elif parse_doc.canonical_name not in (None, UNKNOWN): path = '%s' % parse_doc.canonical_name else: path = '??' # If we've already examined this pair, then there's nothing # more to do. The reason that we check id's here is that we # want to avoid hashing the APIDoc objects for now, so we can # use APIDoc.merge_and_overwrite() later. if (id(introspect_doc), id(parse_doc)) in cyclecheck: return introspect_doc cyclecheck.add( (id(introspect_doc), id(parse_doc)) ) # If these two are already merged, then we're done. (Two # APIDoc's compare equal iff they are identical or have been # merged.) if introspect_doc == parse_doc: return introspect_doc # If both values are GenericValueDoc, then we don't want to merge # them. E.g., we don't want to merge 2+2 with 4. So just copy # the parse_doc's parse_repr to introspect_doc, & return it. # (In particular, do *not* call merge_and_overwrite.) if type(introspect_doc) == type(parse_doc) == GenericValueDoc: if parse_doc.parse_repr is not UNKNOWN: introspect_doc.parse_repr = parse_doc.parse_repr introspect_doc.docs_extracted_by = 'both' return introspect_doc # Perform several sanity checks here -- if we accidentally # merge values that shouldn't get merged, then bad things can # happen. mismatch = None if (introspect_doc.__class__ != parse_doc.__class__ and not (issubclass(introspect_doc.__class__, parse_doc.__class__) or issubclass(parse_doc.__class__, introspect_doc.__class__))): mismatch = ("value types don't match -- i=%r, p=%r." % (introspect_doc.__class__, parse_doc.__class__)) if (isinstance(introspect_doc, ValueDoc) and isinstance(parse_doc, ValueDoc)): if (introspect_doc.pyval is not UNKNOWN and parse_doc.pyval is not UNKNOWN and introspect_doc.pyval is not parse_doc.pyval): mismatch = "values don't match." elif (introspect_doc.canonical_name not in (None, UNKNOWN) and parse_doc.canonical_name not in (None, UNKNOWN) and introspect_doc.canonical_name != parse_doc.canonical_name): mismatch = "canonical names don't match." if mismatch is not None: log.info("Not merging the parsed & introspected values of %s, " "since their %s" % (path, mismatch)) if DEFAULT_MERGE_PRECEDENCE == 'introspect': return introspect_doc else: return parse_doc # If one apidoc's class is a superclass of the other's, then # specialize it to the more specific class. if introspect_doc.__class__ is not parse_doc.__class__: if issubclass(introspect_doc.__class__, parse_doc.__class__): parse_doc.specialize_to(introspect_doc.__class__) if issubclass(parse_doc.__class__, introspect_doc.__class__): introspect_doc.specialize_to(parse_doc.__class__) assert introspect_doc.__class__ is parse_doc.__class__ # The posargs and defaults are tied together -- if we merge # the posargs one way, then we need to merge the defaults the # same way. So check them first. (This is a minor hack) if (isinstance(introspect_doc, RoutineDoc) and isinstance(parse_doc, RoutineDoc)): _merge_posargs_and_defaults(introspect_doc, parse_doc, path) # Merge the two api_doc's attributes. for attrib in set(introspect_doc.__dict__.keys() + parse_doc.__dict__.keys()): # Be sure not to merge any private attributes (especially # __mergeset or __has_been_hashed!) if attrib.startswith('_'): continue merge_attribute(attrib, introspect_doc, parse_doc, cyclecheck, path) # Set the dictionaries to be shared. return introspect_doc.merge_and_overwrite(parse_doc) def _merge_posargs_and_defaults(introspect_doc, parse_doc, path): # If either is unknown, then let merge_attrib handle it. if introspect_doc.posargs is UNKNOWN or parse_doc.posargs is UNKNOWN: return # If the introspected doc just has '...', then trust the parsed doc. if introspect_doc.posargs == ['...'] and parse_doc.posargs != ['...']: introspect_doc.posargs = parse_doc.posargs introspect_doc.posarg_defaults = parse_doc.posarg_defaults # If they are incompatible, then check the precedence. elif introspect_doc.posargs != parse_doc.posargs: log.info("Not merging the parsed & introspected arg " "lists for %s, since they don't match (%s vs %s)" % (path, introspect_doc.posargs, parse_doc.posargs)) if (MERGE_PRECEDENCE.get('posargs', DEFAULT_MERGE_PRECEDENCE) == 'introspect'): parse_doc.posargs = introspect_doc.posargs parse_doc.posarg_defaults = introspect_doc.posarg_defaults else: introspect_doc.posargs = parse_doc.posargs introspect_doc.posarg_defaults = parse_doc.posarg_defaults def merge_attribute(attrib, introspect_doc, parse_doc, cyclecheck, path): precedence = MERGE_PRECEDENCE.get(attrib, DEFAULT_MERGE_PRECEDENCE) if precedence not in ('parse', 'introspect'): raise ValueError('Bad precedence value %r' % precedence) if (getattr(introspect_doc, attrib) is UNKNOWN and getattr(parse_doc, attrib) is not UNKNOWN): setattr(introspect_doc, attrib, getattr(parse_doc, attrib)) elif (getattr(introspect_doc, attrib) is not UNKNOWN and getattr(parse_doc, attrib) is UNKNOWN): setattr(parse_doc, attrib, getattr(introspect_doc, attrib)) elif (getattr(introspect_doc, attrib) is UNKNOWN and getattr(parse_doc, attrib) is UNKNOWN): pass else: # Both APIDoc objects have values; we need to merge them. introspect_val = getattr(introspect_doc, attrib) parse_val = getattr(parse_doc, attrib) if attrib in _attribute_mergefunc_registry: handler = _attribute_mergefunc_registry[attrib] merged_val = handler(introspect_val, parse_val, precedence, cyclecheck, path) elif precedence == 'introspect': merged_val = introspect_val elif precedence == 'parse': merged_val = parse_val setattr(introspect_doc, attrib, merged_val) setattr(parse_doc, attrib, merged_val) def merge_variables(varlist1, varlist2, precedence, cyclecheck, path): # Merge all variables that are in both sets. for varname, var1 in varlist1.items(): var2 = varlist2.get(varname) if var2 is not None: var = merge_docs(var1, var2, cyclecheck, path+'.'+varname) varlist1[varname] = var varlist2[varname] = var # Copy any variables that are not in varlist1 over. for varname, var in varlist2.items(): varlist1.setdefault(varname, var) return varlist1 def merge_value(value1, value2, precedence, cyclecheck, path): assert value1 is not None and value2 is not None return merge_docs(value1, value2, cyclecheck, path) def merge_overrides(v1, v2, precedence, cyclecheck, path): return merge_value(v1, v2, precedence, cyclecheck, path+'.') def merge_fget(v1, v2, precedence, cyclecheck, path): return merge_value(v1, v2, precedence, cyclecheck, path+'.fget') def merge_fset(v1, v2, precedence, cyclecheck, path): return merge_value(v1, v2, precedence, cyclecheck, path+'.fset') def merge_fdel(v1, v2, precedence, cyclecheck, path): return merge_value(v1, v2, precedence, cyclecheck, path+'.fdel') def merge_proxy_for(v1, v2, precedence, cyclecheck, path): # Anything we got from introspection shouldn't have a proxy_for # attribute -- it should be the actual object's documentation. return v1 def merge_bases(baselist1, baselist2, precedence, cyclecheck, path): # Be careful here -- if we get it wrong, then we could end up # merging two unrelated classes, which could lead to bad # things (e.g., a class that's its own subclass). So only # merge two bases if we're quite sure they're the same class. # (In particular, if they have the same canonical name.) # If the lengths don't match up, then give up. This is most # often caused by __metaclass__. if len(baselist1) != len(baselist2): log.info("Not merging the introspected & parsed base lists " "for %s, since their lengths don't match (%s vs %s)" % (path, len(baselist1), len(baselist2))) if precedence == 'introspect': return baselist1 else: return baselist2 # If any names disagree, then give up. for base1, base2 in zip(baselist1, baselist2): if ((base1.canonical_name not in (None, UNKNOWN) and base2.canonical_name not in (None, UNKNOWN)) and base1.canonical_name != base2.canonical_name): log.info("Not merging the parsed & introspected base " "lists for %s, since the bases' names don't match " "(%s vs %s)" % (path, base1.canonical_name, base2.canonical_name)) if precedence == 'introspect': return baselist1 else: return baselist2 for i, (base1, base2) in enumerate(zip(baselist1, baselist2)): base = merge_docs(base1, base2, cyclecheck, '%s.__bases__[%d]' % (path, i)) baselist1[i] = baselist2[i] = base return baselist1 def merge_posarg_defaults(defaults1, defaults2, precedence, cyclecheck, path): if len(defaults1) != len(defaults2): if precedence == 'introspect': return defaults1 else: return defaults2 defaults = [] for i, (d1, d2) in enumerate(zip(defaults1, defaults2)): if d1 is not None and d2 is not None: d_path = '%s.[%d]' % (path, i) defaults.append(merge_docs(d1, d2, cyclecheck, d_path)) elif precedence == 'introspect': defaults.append(d1) else: defaults.append(d2) return defaults def merge_docstring(docstring1, docstring2, precedence, cyclecheck, path): if docstring1 is None or docstring1 is UNKNOWN or precedence=='parse': return docstring2 else: return docstring1 def merge_docs_extracted_by(v1, v2, precedence, cyclecheck, path): return 'both' def merge_submodules(v1, v2, precedence, cyclecheck, path): n1 = sorted([m.canonical_name for m in v1]) n2 = sorted([m.canonical_name for m in v2]) if (n1 != n2) and (n2 != []): log.info('Introspector & parser disagree about submodules ' 'for %s: (%s) vs (%s)' % (path, ', '.join([str(n) for n in n1]), ', '.join([str(n) for n in n2]))) return v1 + [m for m in v2 if m.canonical_name not in n1] return v1 register_attribute_mergefunc('variables', merge_variables) register_attribute_mergefunc('value', merge_value) register_attribute_mergefunc('overrides', merge_overrides) register_attribute_mergefunc('fget', merge_fget) register_attribute_mergefunc('fset', merge_fset) register_attribute_mergefunc('fdel', merge_fdel) register_attribute_mergefunc('proxy_for', merge_proxy_for) register_attribute_mergefunc('bases', merge_bases) register_attribute_mergefunc('posarg_defaults', merge_posarg_defaults) register_attribute_mergefunc('docstring', merge_docstring) register_attribute_mergefunc('docs_extracted_by', merge_docs_extracted_by) register_attribute_mergefunc('submodules', merge_submodules) ###################################################################### ## Import Linking ###################################################################### def link_imports(val_doc, docindex): # Check if the ValueDoc has an unresolved proxy_for link. # If so, then resolve it. while val_doc.proxy_for not in (UNKNOWN, None): # Find the valuedoc that the proxy_for name points to. src_doc = docindex.get_valdoc(val_doc.proxy_for) # If we don't have any valuedoc at that address, then # set that address as its canonical name. # [XXX] Do I really want to do this? if src_doc is None: val_doc.canonical_name = val_doc.proxy_for return # If we *do* have something at that address, then # merge the proxy `val_doc` with it. elif src_doc != val_doc: # Copy any subclass information from val_doc->src_doc. if (isinstance(val_doc, ClassDoc) and isinstance(src_doc, ClassDoc)): for subclass in val_doc.subclasses: if subclass not in src_doc.subclasses: src_doc.subclasses.append(subclass) # Then overwrite val_doc with the contents of src_doc. src_doc.merge_and_overwrite(val_doc, ignore_hash_conflict=True) # If the proxy_for link points back at src_doc # itself, then we most likely have a variable that's # shadowing a submodule that it should be equal to. # So just get rid of the variable. elif src_doc == val_doc: parent_name = val_doc.proxy_for[:-1] var_name = val_doc.proxy_for[-1] parent = docindex.get_valdoc(parent_name) if parent is not None and var_name in parent.variables: del parent.variables[var_name] src_doc.proxy_for = None ###################################################################### ## Canonical Name Assignment ###################################################################### _name_scores = {} """A dictionary mapping from each C{ValueDoc} to the score that has been assigned to its current cannonical name. If L{assign_canonical_names()} finds a canonical name with a better score, then it will replace the old name.""" _unreachable_names = {DottedName(DottedName.UNREACHABLE):1} """The set of names that have been used for unreachable objects. This is used to ensure there are no duplicate cannonical names assigned. C{_unreachable_names} is a dictionary mapping from dotted names to integer ids, where the next unused unreachable name derived from dotted name C{n} is C{DottedName('%s-%s' % (n, str(_unreachable_names[n]+1))}""" def assign_canonical_names(val_doc, name, docindex, score=0): """ Assign a canonical name to C{val_doc} (if it doesn't have one already), and (recursively) to each variable in C{val_doc}. In particular, C{val_doc} will be assigned the canonical name C{name} iff either: - C{val_doc}'s canonical name is C{UNKNOWN}; or - C{val_doc}'s current canonical name was assigned by this method; but the score of the new name (C{score}) is higher than the score of the current name (C{score_dict[val_doc]}). Note that canonical names will even be assigned to values like integers and C{None}; but these should be harmless. """ # If we've already visited this node, and our new score # doesn't beat our old score, then there's nothing more to do. # Note that since score increases strictly monotonically, this # also prevents us from going in cycles. if val_doc in _name_scores and score <= _name_scores[val_doc]: return # Update val_doc's canonical name, if appropriate. if (val_doc not in _name_scores and val_doc.canonical_name is not UNKNOWN): # If this is the first time we've seen val_doc, and it # already has a name, then don't change that name. _name_scores[val_doc] = sys.maxint name = val_doc.canonical_name score = 0 else: # Otherwise, update the name iff the new score is better # than the old one. if (val_doc not in _name_scores or score > _name_scores[val_doc]): val_doc.canonical_name = name _name_scores[val_doc] = score # Recurse to any contained values. if isinstance(val_doc, NamespaceDoc): for var_doc in val_doc.variables.values(): # Set the variable's canonical name. varname = DottedName(name, var_doc.name) var_doc.canonical_name = varname # If the value is unknown, or is a generic value doc, then # the valuedoc doesn't get assigned a name; move on. if (var_doc.value is UNKNOWN or isinstance(var_doc.value, GenericValueDoc)): continue # [XX] After svn commit 1644-1647, I'm not sure if this # ever gets used: This check is for cases like # curses.wrapper, where an imported variable shadows its # value's "real" location. if _var_shadows_self(var_doc, varname): _fix_self_shadowing_var(var_doc, varname, docindex) # Find the score for this new name. vardoc_score = score-1 if var_doc.is_imported is UNKNOWN: vardoc_score -= 10 elif var_doc.is_imported: vardoc_score -= 100 if var_doc.is_alias is UNKNOWN: vardoc_score -= 10 elif var_doc.is_alias: vardoc_score -= 1000 assign_canonical_names(var_doc.value, varname, docindex, vardoc_score) # Recurse to any directly reachable values. for val_doc_2 in val_doc.apidoc_links(variables=False): val_name, val_score = _unreachable_name_for(val_doc_2, docindex) assign_canonical_names(val_doc_2, val_name, docindex, val_score) def _var_shadows_self(var_doc, varname): return (var_doc.value not in (None, UNKNOWN) and var_doc.value.canonical_name not in (None, UNKNOWN) and var_doc.value.canonical_name != varname and varname.dominates(var_doc.value.canonical_name)) def _fix_self_shadowing_var(var_doc, varname, docindex): # If possible, find another name for the shadowed value. cname = var_doc.value.canonical_name for i in range(1, len(cname)-1): new_name = cname[:i] + (cname[i]+"'") + cname[i+1:] val_doc = docindex.get_valdoc(new_name) if val_doc is not None: log.warning("%s shadows its own value -- using %s instead" % (varname, new_name)) var_doc.value = val_doc return # If we couldn't find the actual value, use an unreachable name. name, score = _unreachable_name_for(var_doc.value, docindex) log.warning('%s shadows itself -- using %s instead' % (varname, name)) var_doc.value.canonical_name = name def _unreachable_name_for(val_doc, docindex): assert isinstance(val_doc, ValueDoc) # [xx] (when) does this help? if (isinstance(val_doc, ModuleDoc) and len(val_doc.canonical_name)==1 and val_doc.package is None): for root_val in docindex.root: if root_val.canonical_name == val_doc.canonical_name: if root_val != val_doc: log.error("Name conflict: %r vs %r" % (val_doc, root_val)) break else: return val_doc.canonical_name, -1000 # Assign it an 'unreachable' name: if (val_doc.pyval is not UNKNOWN and hasattr(val_doc.pyval, '__name__')): try: name = DottedName(DottedName.UNREACHABLE, val_doc.pyval.__name__, strict=True) except DottedName.InvalidDottedName: name = DottedName(DottedName.UNREACHABLE) else: name = DottedName(DottedName.UNREACHABLE) # Uniquify the name. if name in _unreachable_names: _unreachable_names[name] += 1 name = DottedName('%s-%s' % (name, _unreachable_names[name]-1)) else: _unreachable_names[name] = 1 return name, -10000 ###################################################################### ## Documentation Inheritance ###################################################################### def find_overrides(class_doc): """ Set the C{overrides} attribute for all variables in C{class_doc}. This needs to be done early (before docstring parsing), so we can know which docstrings to suppress warnings for. """ for base_class in list(class_doc.mro(warn_about_bad_bases=True)): if base_class == class_doc: continue if base_class.variables is UNKNOWN: continue for name, var_doc in base_class.variables.items(): if ( not (name.startswith('__') and not name.endswith('__')) and base_class == var_doc.container and name in class_doc.variables and class_doc.variables[name].container==class_doc and class_doc.variables[name].overrides is UNKNOWN ): class_doc.variables[name].overrides = var_doc def inherit_docs(class_doc): for base_class in list(class_doc.mro(warn_about_bad_bases=True)): if base_class == class_doc: continue # Inherit any groups. Place them *after* this class's groups, # so that any groups that are important to this class come # first. if base_class.group_specs not in (None, UNKNOWN): class_doc.group_specs += [gs for gs in base_class.group_specs if gs not in class_doc.group_specs] # Inherit any variables. if base_class.variables is UNKNOWN: continue for name, var_doc in base_class.variables.items(): # If it's a __private variable, then don't inherit it. if name.startswith('__') and not name.endswith('__'): continue # Inhetit only from the defining class. Or else, in case of # multiple inheritance, we may import from a grand-ancestor # variables overridden by a class that follows in mro. if base_class != var_doc.container: continue # If class_doc doesn't have a variable with this name, # then inherit it. if name not in class_doc.variables: class_doc.variables[name] = var_doc # Otherwise, class_doc already contains a variable # that shadows var_doc. But if class_doc's var is # local, then record the fact that it overrides # var_doc. elif class_doc.variables[name].container==class_doc: class_doc.variables[name].overrides = var_doc _inherit_info(class_doc.variables[name]) _INHERITED_ATTRIBS = [ 'descr', 'summary', 'metadata', 'extra_docstring_fields', 'type_descr', 'arg_descrs', 'arg_types', 'return_descr', 'return_type', 'exception_descrs'] _method_descriptor = type(list.append) def _inherit_info(var_doc): """ Copy any relevant documentation information from the variable that C{var_doc} overrides into C{var_doc} itself. """ src_var = var_doc.overrides src_val = var_doc.overrides.value val_doc = var_doc.value # Special case: if the source value and target values are both c # extension methods, and the target value's signature is not # specified, then inherit the source value's signature. if (isinstance(val_doc, RoutineDoc) and isinstance(src_val, RoutineDoc) and (inspect.isbuiltin(val_doc.pyval) or isinstance(val_doc.pyval, _method_descriptor)) and (inspect.isbuiltin(src_val.pyval) or isinstance(src_val.pyval, _method_descriptor)) and val_doc.all_args() in (['...'], UNKNOWN) and src_val.all_args() not in (['...'], UNKNOWN)): for attrib in ['posargs', 'posarg_defaults', 'vararg', 'kwarg', 'return_type']: setattr(val_doc, attrib, getattr(src_val, attrib)) # If the new variable has a docstring, then don't inherit # anything, even if the docstring is blank. if var_doc.docstring not in (None, UNKNOWN): return # [xx] Do I want a check like this:? # # If it's a method and the signature doesn't match well enough, # # then give up. # if (isinstance(src_val, RoutineDoc) and # isinstance(val_doc, RoutineDoc)): # if (src_val.posargs != val_doc.posargs[:len(src_val.posargs)] or # src_val.vararg != None and src_val.vararg != val_doc.vararg): # log.docstring_warning( # "The signature of %s does not match the signature of the " # "method it overrides (%s); not inheriting documentation." % # (var_doc.canonical_name, src_var.canonical_name)) # return # Inherit attributes! for attrib in _INHERITED_ATTRIBS: if (hasattr(var_doc, attrib) and hasattr(src_var, attrib) and getattr(src_var, attrib) not in (None, UNKNOWN)): setattr(var_doc, attrib, getattr(src_var, attrib)) elif (src_val is not None and hasattr(val_doc, attrib) and hasattr(src_val, attrib) and getattr(src_val, attrib) not in (None, UNKNOWN) and getattr(val_doc, attrib) in (None, UNKNOWN, [])): setattr(val_doc, attrib, getattr(src_val, attrib)) epydoc-3.0.1+dfsg/epydoc/docstringparser.py0000644000175000017500000013055510750072375021262 0ustar pronovicpronovic# epydoc -- Docstring processing # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: docstringparser.py 1689 2008-01-30 17:01:02Z edloper $ """ Parse docstrings and handle any fields it defines, such as C{@type} and C{@author}. Fields are used to describe specific information about an object. There are two classes of fields: X{simple fields} and X{special fields}. Simple fields are fields that get stored directly in an C{APIDoc}'s metadata dictionary, without any special processing. The set of simple fields is defined by the list L{STANDARD_FIELDS}, whose elements are L{DocstringField}s. Special fields are fields that perform some sort of processing on the C{APIDoc}, or add information to attributes other than the metadata dictionary. Special fields are are handled by field handler functions, which are registered using L{register_field_handler}. """ __docformat__ = 'epytext en' ###################################################################### ## Imports ###################################################################### import re, sys from epydoc import markup from epydoc.markup import epytext from epydoc.apidoc import * from epydoc.docintrospecter import introspect_docstring_lineno from epydoc.util import py_src_filename from epydoc import log import epydoc.docparser import __builtin__, exceptions ###################################################################### # Docstring Fields ###################################################################### class DocstringField: """ A simple docstring field, which can be used to describe specific information about an object, such as its author or its version. Simple docstring fields are fields that take no arguments, and are displayed as simple sections. @ivar tags: The set of tags that can be used to identify this field. @ivar singular: The label that should be used to identify this field in the output, if the field contains one value. @ivar plural: The label that should be used to identify this field in the output, if the field contains multiple values. @ivar short: If true, then multiple values should be combined into a single comma-delimited list. If false, then multiple values should be listed separately in a bulleted list. @ivar multivalue: If true, then multiple values may be given for this field; if false, then this field can only take a single value, and a warning should be issued if it is redefined. @ivar takes_arg: If true, then this field expects an argument; and a separate field section will be constructed for each argument value. The label (and plural label) should include a '%s' to mark where the argument's string rep should be added. """ def __init__(self, tags, label, plural=None, short=0, multivalue=1, takes_arg=0, varnames=None): if type(tags) in (list, tuple): self.tags = tuple(tags) elif type(tags) is str: self.tags = (tags,) else: raise TypeError('Bad tags: %s' % tags) self.singular = label if plural is None: self.plural = label else: self.plural = plural self.multivalue = multivalue self.short = short self.takes_arg = takes_arg self.varnames = varnames or [] def __cmp__(self, other): if not isinstance(other, DocstringField): return -1 return cmp(self.tags, other.tags) def __hash__(self): return hash(self.tags) def __repr__(self): return '' % self.tags[0] STANDARD_FIELDS = [ #: A list of the standard simple fields accepted by epydoc. This #: list can be augmented at run-time by a docstring with the special #: C{@deffield} field. The order in which fields are listed here #: determines the order in which they will be displayed in the #: output. # If it's deprecated, put that first. DocstringField(['deprecated', 'depreciated'], 'Deprecated', multivalue=0, varnames=['__deprecated__']), # Status info DocstringField(['version'], 'Version', multivalue=0, varnames=['__version__']), DocstringField(['date'], 'Date', multivalue=0, varnames=['__date__']), DocstringField(['status'], 'Status', multivalue=0), # Bibliographic Info DocstringField(['author', 'authors'], 'Author', 'Authors', short=1, varnames=['__author__', '__authors__']), DocstringField(['contact'], 'Contact', 'Contacts', short=1, varnames=['__contact__']), DocstringField(['organization', 'org'], 'Organization', 'Organizations'), DocstringField(['copyright', '(c)'], 'Copyright', multivalue=0, varnames=['__copyright__']), DocstringField(['license'], 'License', multivalue=0, varnames=['__license__']), # Various warnings etc. DocstringField(['bug'], 'Bug', 'Bugs'), DocstringField(['warning', 'warn'], 'Warning', 'Warnings'), DocstringField(['attention'], 'Attention'), DocstringField(['note'], 'Note', 'Notes'), # Formal conditions DocstringField(['requires', 'require', 'requirement'], 'Requires'), DocstringField(['precondition', 'precond'], 'Precondition', 'Preconditions'), DocstringField(['postcondition', 'postcond'], 'Postcondition', 'Postconditions'), DocstringField(['invariant'], 'Invariant'), # When was it introduced (version # or date) DocstringField(['since'], 'Since', multivalue=0), # Changes made DocstringField(['change', 'changed'], 'Change Log'), # Crossreferences DocstringField(['see', 'seealso'], 'See Also', short=1), # Future Work DocstringField(['todo'], 'To Do', takes_arg=True), # Permissions (used by zope-based projects) DocstringField(['permission', 'permissions'], 'Permission', 'Permissions') ] ###################################################################### #{ Docstring Parsing ###################################################################### DEFAULT_DOCFORMAT = 'epytext' """The name of the default markup languge used to process docstrings.""" # [xx] keep track of which ones we've already done, in case we're # asked to process one twice? e.g., for @include we might have to # parse the included docstring earlier than we might otherwise..?? def parse_docstring(api_doc, docindex, suppress_warnings=[]): """ Process the given C{APIDoc}'s docstring. In particular, populate the C{APIDoc}'s C{descr} and C{summary} attributes, and add any information provided by fields in the docstring. @param docindex: A DocIndex, used to find the containing module (to look up the docformat); and to find any user docfields defined by containing objects. @param suppress_warnings: A set of objects for which docstring warnings should be suppressed. """ if api_doc.metadata is not UNKNOWN: if not (isinstance(api_doc, RoutineDoc) and api_doc.canonical_name[-1] == '__init__'): log.debug("%s's docstring processed twice" % api_doc.canonical_name) return initialize_api_doc(api_doc) # If there's no docstring, then check for special variables (e.g., # __version__), and then return -- there's nothing else to do. if (api_doc.docstring in (None, UNKNOWN)): if isinstance(api_doc, NamespaceDoc): for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): add_metadata_from_var(api_doc, field) return # Remove leading indentation from the docstring. api_doc.docstring = unindent_docstring(api_doc.docstring) # Decide which docformat is used by this module. docformat = get_docformat(api_doc, docindex) # A list of markup errors from parsing. parse_errors = [] # Extract a signature from the docstring, if it has one. This # overrides any signature we got via introspection/parsing. if isinstance(api_doc, RoutineDoc): parse_function_signature(api_doc, None, docformat, parse_errors) # Parse the docstring. Any errors encountered are stored as # `ParseError` objects in the errors list. parsed_docstring = markup.parse(api_doc.docstring, docformat, parse_errors) # Divide the docstring into a description and a list of # fields. descr, fields = parsed_docstring.split_fields(parse_errors) api_doc.descr = descr field_warnings = [] # Handle the constructor fields that have been defined in the class # docstring. This code assumes that a class docstring is parsed before # the same class __init__ docstring. if isinstance(api_doc, ClassDoc): # Parse ahead the __init__ docstring for this class initvar = api_doc.variables.get('__init__') if initvar and isinstance(initvar.value, RoutineDoc): init_api_doc = initvar.value parse_docstring(init_api_doc, docindex, suppress_warnings) parse_function_signature(init_api_doc, api_doc, docformat, parse_errors) init_fields = split_init_fields(fields, field_warnings) # Process fields for field in init_fields: try: process_field(init_api_doc, docindex, field.tag(), field.arg(), field.body()) except ValueError, e: field_warnings.append(str(e)) # Process fields for field in fields: try: process_field(api_doc, docindex, field.tag(), field.arg(), field.body()) except ValueError, e: field_warnings.append(str(e)) # Check to make sure that all type parameters correspond to # some documented parameter. check_type_fields(api_doc, field_warnings) # Check for special variables (e.g., __version__) if isinstance(api_doc, NamespaceDoc): for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): add_metadata_from_var(api_doc, field) # Extract a summary if api_doc.summary is None and api_doc.descr is not None: api_doc.summary, api_doc.other_docs = api_doc.descr.summary() # If the summary is empty, but the return field is not, then use # the return field to generate a summary description. if (isinstance(api_doc, RoutineDoc) and api_doc.summary is None and api_doc.return_descr is not None): s, o = api_doc.return_descr.summary() api_doc.summary = RETURN_PDS + s api_doc.other_docs = o # [XX] Make sure we don't have types/param descrs for unknown # vars/params? # Report any errors that occured if api_doc in suppress_warnings: if parse_errors or field_warnings: log.info("Suppressing docstring warnings for %s, since it " "is not included in the documented set." % api_doc.canonical_name) else: report_errors(api_doc, docindex, parse_errors, field_warnings) def add_metadata_from_var(api_doc, field): for varname in field.varnames: # Check if api_doc has a variable w/ the given name. if varname not in api_doc.variables: continue # Check moved here from before the for loop because we expect to # reach rarely this point. The loop below is to be performed more than # once only for fields with more than one varname, which currently is # only 'author'. for md in api_doc.metadata: if field == md[0]: return # We already have a value for this metadata. var_doc = api_doc.variables[varname] if var_doc.value is UNKNOWN: continue val_doc = var_doc.value value = [] # Try extracting the value from the pyval. ok_types = (basestring, int, float, bool, type(None)) if val_doc.pyval is not UNKNOWN: if isinstance(val_doc.pyval, ok_types): value = [val_doc.pyval] elif field.multivalue: if isinstance(val_doc.pyval, (tuple, list)): for elt in val_doc.pyval: if not isinstance(elt, ok_types): break else: value = list(val_doc.pyval) # Try extracting the value from the parse tree. elif val_doc.toktree is not UNKNOWN: try: value = [epydoc.docparser.parse_string(val_doc.toktree)] except KeyboardInterrupt: raise except: pass if field.multivalue and not value: try: value = epydoc.docparser.parse_string_list(val_doc.toktree) except KeyboardInterrupt: raise except: raise # Add any values that we found. for elt in value: if isinstance(elt, str): elt = decode_with_backslashreplace(elt) else: elt = unicode(elt) elt = epytext.ParsedEpytextDocstring( epytext.parse_as_para(elt), inline=True) # Add in the metadata and remove from the variables api_doc.metadata.append( (field, varname, elt) ) # Remove the variable itself (unless it's documented) if var_doc.docstring in (None, UNKNOWN): del api_doc.variables[varname] if api_doc.sort_spec is not UNKNOWN: try: api_doc.sort_spec.remove(varname) except ValueError: pass def initialize_api_doc(api_doc): """A helper function for L{parse_docstring()} that initializes the attributes that C{parse_docstring()} will write to.""" if api_doc.descr is UNKNOWN: api_doc.descr = None if api_doc.summary is UNKNOWN: api_doc.summary = None if api_doc.metadata is UNKNOWN: api_doc.metadata = [] if isinstance(api_doc, RoutineDoc): if api_doc.arg_descrs is UNKNOWN: api_doc.arg_descrs = [] if api_doc.arg_types is UNKNOWN: api_doc.arg_types = {} if api_doc.return_descr is UNKNOWN: api_doc.return_descr = None if api_doc.return_type is UNKNOWN: api_doc.return_type = None if api_doc.exception_descrs is UNKNOWN: api_doc.exception_descrs = [] if isinstance(api_doc, (VariableDoc, PropertyDoc)): if api_doc.type_descr is UNKNOWN: api_doc.type_descr = None if isinstance(api_doc, NamespaceDoc): if api_doc.group_specs is UNKNOWN: api_doc.group_specs = [] if api_doc.sort_spec is UNKNOWN: api_doc.sort_spec = [] def split_init_fields(fields, warnings): """ Remove the fields related to the constructor from a class docstring fields list. @param fields: The fields to process. The list will be modified in place @type fields: C{list} of L{markup.Field} @param warnings: A list to emit processing warnings @type warnings: C{list} @return: The C{fields} items to be applied to the C{__init__} method @rtype: C{list} of L{markup.Field} """ init_fields = [] # Split fields in lists according to their argument, keeping order. arg_fields = {} args_order = [] i = 0 while i < len(fields): field = fields[i] # gather together all the fields with the same arg if field.arg() is not None: arg_fields.setdefault(field.arg(), []).append(fields.pop(i)) args_order.append(field.arg()) else: i += 1 # Now check that for each argument there is at most a single variable # and a single parameter, and at most a single type for each of them. for arg in args_order: ff = arg_fields.pop(arg, None) if ff is None: continue var = tvar = par = tpar = None for field in ff: if field.tag() in VARIABLE_TAGS: if var is None: var = field fields.append(field) else: warnings.append( "There is more than one variable named '%s'" % arg) elif field.tag() in PARAMETER_TAGS: if par is None: par = field init_fields.append(field) else: warnings.append( "There is more than one parameter named '%s'" % arg) elif field.tag() == 'type': if var is None and par is None: # type before obj tvar = tpar = field else: if var is not None and tvar is None: tvar = field if par is not None and tpar is None: tpar = field elif field.tag() in EXCEPTION_TAGS: init_fields.append(field) else: # Unespected field fields.append(field) # Put selected types into the proper output lists if tvar is not None: if var is not None: fields.append(tvar) else: pass # [xx] warn about type w/o object? if tpar is not None: if par is not None: init_fields.append(tpar) else: pass # [xx] warn about type w/o object? return init_fields def report_errors(api_doc, docindex, parse_errors, field_warnings): """A helper function for L{parse_docstring()} that reports any markup warnings and field warnings that we encountered while processing C{api_doc}'s docstring.""" if not parse_errors and not field_warnings: return # Get the name of the item containing the error, and the # filename of its containing module. name = api_doc.canonical_name module = api_doc.defining_module if module is not UNKNOWN and module.filename not in (None, UNKNOWN): try: filename = py_src_filename(module.filename) except: filename = module.filename else: filename = '??' # [xx] Don't report markup errors for standard builtins. # n.b. that we must use 'is' to compare pyvals here -- if we use # 'in' or '==', then a user __cmp__ method might raise an # exception, or lie. if isinstance(api_doc, ValueDoc) and api_doc != module: if module not in (None, UNKNOWN) and module.pyval is exceptions: return for builtin_val in __builtin__.__dict__.values(): if builtin_val is api_doc.pyval: return # Get the start line of the docstring containing the error. startline = api_doc.docstring_lineno if startline in (None, UNKNOWN): startline = introspect_docstring_lineno(api_doc) if startline in (None, UNKNOWN): startline = None # Display a block header. header = 'File %s, ' % filename if startline is not None: header += 'line %d, ' % startline header += 'in %s' % name log.start_block(header) # Display all parse errors. But first, combine any errors # with duplicate description messages. if startline is None: # remove dups, but keep original order: dups = {} for error in parse_errors: message = error.descr() if message not in dups: log.docstring_warning(message) dups[message] = 1 else: # Combine line number fields for dup messages: messages = {} # maps message -> list of linenum for error in parse_errors: error.set_linenum_offset(startline) message = error.descr() messages.setdefault(message, []).append(error.linenum()) message_items = messages.items() message_items.sort(lambda a,b:cmp(min(a[1]), min(b[1]))) for message, linenums in message_items: linenums = [n for n in linenums if n is not None] if len(linenums) == 0: log.docstring_warning(message) elif len(linenums) == 1: log.docstring_warning("Line %s: %s" % (linenums[0], message)) else: linenums = ', '.join(['%s' % l for l in linenums]) log.docstring_warning("Lines %s: %s" % (linenums, message)) # Display all field warnings. for warning in field_warnings: log.docstring_warning(warning) # End the message block. log.end_block() RETURN_PDS = markup.parse('Returns:', markup='epytext') """A ParsedDocstring containing the text 'Returns'. This is used to construct summary descriptions for routines that have empty C{descr}, but non-empty C{return_descr}.""" RETURN_PDS._tree.children[0].attribs['inline'] = True ###################################################################### #{ Field Processing Error Messages ###################################################################### UNEXPECTED_ARG = '%r did not expect an argument' EXPECTED_ARG = '%r expected an argument' EXPECTED_SINGLE_ARG = '%r expected a single argument' BAD_CONTEXT = 'Invalid context for %r' REDEFINED = 'Redefinition of %s' UNKNOWN_TAG = 'Unknown field tag %r' BAD_PARAM = '@%s for unknown parameter %s' ###################################################################### #{ Field Processing ###################################################################### def process_field(api_doc, docindex, tag, arg, descr): """ Process a single field, and use it to update C{api_doc}. If C{tag} is the name of a special field, then call its handler function. If C{tag} is the name of a simple field, then use C{process_simple_field} to process it. Otherwise, check if it's a user-defined field, defined in this docstring or the docstring of a containing object; and if so, process it with C{process_simple_field}. @param tag: The field's tag, such as C{'author'} @param arg: The field's optional argument @param descr: The description following the field tag and argument. @raise ValueError: If a problem was encountered while processing the field. The C{ValueError}'s string argument is an explanation of the problem, which should be displayed as a warning message. """ # standard special fields if tag in _field_dispatch_table: handler = _field_dispatch_table[tag] handler(api_doc, docindex, tag, arg, descr) return # standard simple fields & user-defined fields for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): if tag in field.tags: # [xx] check if it's redefined if it's not multivalue?? if not field.takes_arg: _check(api_doc, tag, arg, expect_arg=False) api_doc.metadata.append((field, arg, descr)) return # If we didn't handle the field, then report a warning. raise ValueError(UNKNOWN_TAG % tag) def user_docfields(api_doc, docindex): """ Return a list of user defined fields that can be used for the given object. This list is taken from the given C{api_doc}, and any of its containing C{NamepaceDoc}s. @note: We assume here that a parent's docstring will always be parsed before its childrens'. This is indeed the case when we are called via L{docbuilder.build_doc_index()}. If a child's docstring is parsed before its parents, then its parent won't yet have had its C{extra_docstring_fields} attribute initialized. """ docfields = [] # Get any docfields from `api_doc` itself if api_doc.extra_docstring_fields not in (None, UNKNOWN): docfields += api_doc.extra_docstring_fields # Get any docfields from `api_doc`'s ancestors for i in range(len(api_doc.canonical_name)-1, 0, -1): ancestor = docindex.get_valdoc(api_doc.canonical_name[:i]) if ancestor is not None \ and ancestor.extra_docstring_fields not in (None, UNKNOWN): docfields += ancestor.extra_docstring_fields return docfields _field_dispatch_table = {} def register_field_handler(handler, *field_tags): """ Register the given field handler function for processing any of the given field tags. Field handler functions should have the following signature: >>> def field_handler(api_doc, docindex, tag, arg, descr): ... '''update api_doc in response to the field.''' Where C{api_doc} is the documentation object to update; C{docindex} is a L{DocIndex} that can be used to look up the documentation for related objects; C{tag} is the field tag that was used; C{arg} is the optional argument; and C{descr} is the description following the field tag and argument. """ for field_tag in field_tags: _field_dispatch_table[field_tag] = handler ###################################################################### #{ Field Handler Functions ###################################################################### def process_summary_field(api_doc, docindex, tag, arg, descr): """Store C{descr} in C{api_doc.summary}""" _check(api_doc, tag, arg, expect_arg=False) if api_doc.summary is not None: raise ValueError(REDEFINED % tag) api_doc.summary = descr def process_include_field(api_doc, docindex, tag, arg, descr): """Copy the docstring contents from the object named in C{descr}""" _check(api_doc, tag, arg, expect_arg=False) # options: # a. just append the descr to our own # b. append descr and update metadata # c. append descr and process all fields. # in any case, mark any errors we may find as coming from an # imported docstring. # how does this interact with documentation inheritance?? raise ValueError('%s not implemented yet' % tag) def process_undocumented_field(api_doc, docindex, tag, arg, descr): """Remove any documentation for the variables named in C{descr}""" _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False) for ident in _descr_to_identifiers(descr): var_name_re = re.compile('^%s$' % ident.replace('*', '(.*)')) for var_name, var_doc in api_doc.variables.items(): if var_name_re.match(var_name): # Remove the variable from `variables`. api_doc.variables.pop(var_name, None) if api_doc.sort_spec is not UNKNOWN: try: api_doc.sort_spec.remove(var_name) except ValueError: pass # For modules, remove any submodules that match var_name_re. if isinstance(api_doc, ModuleDoc): removed = set([m for m in api_doc.submodules if var_name_re.match(m.canonical_name[-1])]) if removed: # Remove the indicated submodules from this module. api_doc.submodules = [m for m in api_doc.submodules if m not in removed] # Remove all ancestors of the indicated submodules # from the docindex root. E.g., if module x # declares y to be undocumented, then x.y.z should # also be undocumented. for elt in docindex.root[:]: for m in removed: if m.canonical_name.dominates(elt.canonical_name): docindex.root.remove(elt) def process_group_field(api_doc, docindex, tag, arg, descr): """Define a group named C{arg} containing the variables whose names are listed in C{descr}.""" _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=True) api_doc.group_specs.append( (arg, _descr_to_identifiers(descr)) ) # [xx] should this also set sort order? def process_deffield_field(api_doc, docindex, tag, arg, descr): """Define a new custom field.""" _check(api_doc, tag, arg, expect_arg=True) if api_doc.extra_docstring_fields is UNKNOWN: api_doc.extra_docstring_fields = [] try: docstring_field = _descr_to_docstring_field(arg, descr) docstring_field.varnames.append("__%s__" % arg) api_doc.extra_docstring_fields.append(docstring_field) except ValueError, e: raise ValueError('Bad %s: %s' % (tag, e)) def process_raise_field(api_doc, docindex, tag, arg, descr): """Record the fact that C{api_doc} can raise the exception named C{tag} in C{api_doc.exception_descrs}.""" _check(api_doc, tag, arg, context=RoutineDoc, expect_arg='single') try: name = DottedName(arg, strict=True) except DottedName.InvalidDottedName: name = arg api_doc.exception_descrs.append( (name, descr) ) def process_sort_field(api_doc, docindex, tag, arg, descr): _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False) api_doc.sort_spec = _descr_to_identifiers(descr) + api_doc.sort_spec # [xx] should I notice when they give a type for an unknown var? def process_type_field(api_doc, docindex, tag, arg, descr): # In namespace, "@type var: ..." describes the type of a var. if isinstance(api_doc, NamespaceDoc): _check(api_doc, tag, arg, expect_arg='single') set_var_type(api_doc, arg, descr) # For variables & properties, "@type: ..." describes the variable. elif isinstance(api_doc, (VariableDoc, PropertyDoc)): _check(api_doc, tag, arg, expect_arg=False) if api_doc.type_descr is not None: raise ValueError(REDEFINED % tag) api_doc.type_descr = descr # For routines, "@type param: ..." describes a parameter. elif isinstance(api_doc, RoutineDoc): _check(api_doc, tag, arg, expect_arg='single') if arg in api_doc.arg_types: raise ValueError(REDEFINED % ('type for '+arg)) api_doc.arg_types[arg] = descr else: raise ValueError(BAD_CONTEXT % tag) def process_var_field(api_doc, docindex, tag, arg, descr): _check(api_doc, tag, arg, context=ModuleDoc, expect_arg=True) for ident in re.split('[:;, ] *', arg): set_var_descr(api_doc, ident, descr) def process_cvar_field(api_doc, docindex, tag, arg, descr): # If @cvar is used *within* a variable, then use it as the # variable's description, and treat the variable as a class var. if (isinstance(api_doc, VariableDoc) and isinstance(api_doc.container, ClassDoc)): _check(api_doc, tag, arg, expect_arg=False) api_doc.is_instvar = False api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr) api_doc.summary, api_doc.other_docs = descr.summary() # Otherwise, @cvar should be used in a class. else: _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True) for ident in re.split('[:;, ] *', arg): set_var_descr(api_doc, ident, descr) api_doc.variables[ident].is_instvar = False def process_ivar_field(api_doc, docindex, tag, arg, descr): # If @ivar is used *within* a variable, then use it as the # variable's description, and treat the variable as an instvar. if (isinstance(api_doc, VariableDoc) and isinstance(api_doc.container, ClassDoc)): _check(api_doc, tag, arg, expect_arg=False) # require that there be no other descr? api_doc.is_instvar = True api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr) api_doc.summary, api_doc.other_docs = descr.summary() # Otherwise, @ivar should be used in a class. else: _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True) for ident in re.split('[:;, ] *', arg): set_var_descr(api_doc, ident, descr) api_doc.variables[ident].is_instvar = True # [xx] '@return: foo' used to get used as a descr if no other # descr was present. is that still true? def process_return_field(api_doc, docindex, tag, arg, descr): _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=False) if api_doc.return_descr is not None: raise ValueError(REDEFINED % 'return value description') api_doc.return_descr = descr def process_rtype_field(api_doc, docindex, tag, arg, descr): _check(api_doc, tag, arg, context=(RoutineDoc, PropertyDoc), expect_arg=False) if isinstance(api_doc, RoutineDoc): if api_doc.return_type is not None: raise ValueError(REDEFINED % 'return value type') api_doc.return_type = descr elif isinstance(api_doc, PropertyDoc): _check(api_doc, tag, arg, expect_arg=False) if api_doc.type_descr is not None: raise ValueError(REDEFINED % tag) api_doc.type_descr = descr def process_arg_field(api_doc, docindex, tag, arg, descr): _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True) idents = re.split('[:;, ] *', arg) api_doc.arg_descrs.append( (idents, descr) ) # Check to make sure that the documented parameter(s) are # actually part of the function signature. all_args = api_doc.all_args() if all_args not in (['...'], UNKNOWN): bad_params = ['"%s"' % i for i in idents if i not in all_args] if bad_params: raise ValueError(BAD_PARAM % (tag, ', '.join(bad_params))) def process_kwarg_field(api_doc, docindex, tag, arg, descr): # [xx] these should -not- be checked if they exist.. # and listed separately or not?? _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True) idents = re.split('[:;, ] *', arg) api_doc.arg_descrs.append( (idents, descr) ) register_field_handler(process_group_field, 'group') register_field_handler(process_deffield_field, 'deffield', 'newfield') register_field_handler(process_sort_field, 'sort') register_field_handler(process_summary_field, 'summary') register_field_handler(process_undocumented_field, 'undocumented') register_field_handler(process_include_field, 'include') register_field_handler(process_var_field, 'var', 'variable') register_field_handler(process_type_field, 'type') register_field_handler(process_cvar_field, 'cvar', 'cvariable') register_field_handler(process_ivar_field, 'ivar', 'ivariable') register_field_handler(process_return_field, 'return', 'returns') register_field_handler(process_rtype_field, 'rtype', 'returntype') register_field_handler(process_arg_field, 'arg', 'argument', 'parameter', 'param') register_field_handler(process_kwarg_field, 'kwarg', 'keyword', 'kwparam') register_field_handler(process_raise_field, 'raise', 'raises', 'except', 'exception') # Tags related to function parameters PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param', 'kwarg', 'keyword', 'kwparam') # Tags related to variables in a class VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable') # Tags related to exceptions EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception') ###################################################################### #{ Helper Functions ###################################################################### def check_type_fields(api_doc, field_warnings): """Check to make sure that all type fields correspond to some documented parameter; if not, append a warning to field_warnings.""" if isinstance(api_doc, RoutineDoc): for arg in api_doc.arg_types: if arg not in api_doc.all_args(): for args, descr in api_doc.arg_descrs: if arg in args: break else: field_warnings.append(BAD_PARAM % ('type', '"%s"' % arg)) def set_var_descr(api_doc, ident, descr): if ident not in api_doc.variables: api_doc.variables[ident] = VariableDoc( container=api_doc, name=ident, canonical_name=api_doc.canonical_name+ident) var_doc = api_doc.variables[ident] if var_doc.descr not in (None, UNKNOWN): raise ValueError(REDEFINED % ('description for '+ident)) var_doc.descr = descr if var_doc.summary in (None, UNKNOWN): var_doc.summary, var_doc.other_docs = var_doc.descr.summary() def set_var_type(api_doc, ident, descr): if ident not in api_doc.variables: api_doc.variables[ident] = VariableDoc( container=api_doc, name=ident, canonical_name=api_doc.canonical_name+ident) var_doc = api_doc.variables[ident] if var_doc.type_descr not in (None, UNKNOWN): raise ValueError(REDEFINED % ('type for '+ident)) var_doc.type_descr = descr def _check(api_doc, tag, arg, context=None, expect_arg=None): if context is not None: if not isinstance(api_doc, context): raise ValueError(BAD_CONTEXT % tag) if expect_arg is not None: if expect_arg == True: if arg is None: raise ValueError(EXPECTED_ARG % tag) elif expect_arg == False: if arg is not None: raise ValueError(UNEXPECTED_ARG % tag) elif expect_arg == 'single': if (arg is None or ' ' in arg): raise ValueError(EXPECTED_SINGLE_ARG % tag) else: assert 0, 'bad value for expect_arg' def get_docformat(api_doc, docindex): """ Return the name of the markup language that should be used to parse the API documentation for the given object. """ # Find the module that defines api_doc. module = api_doc.defining_module # Look up its docformat. if module is not UNKNOWN and module.docformat not in (None, UNKNOWN): docformat = module.docformat else: docformat = DEFAULT_DOCFORMAT # Convert to lower case & strip region codes. try: return docformat.lower().split()[0] except: return DEFAULT_DOCFORMAT def unindent_docstring(docstring): # [xx] copied from inspect.getdoc(); we can't use inspect.getdoc() # itself, since it expects an object, not a string. if not docstring: return '' lines = docstring.expandtabs().split('\n') # Find minimum indentation of any non-blank lines after first line. margin = sys.maxint for line in lines[1:]: content = len(line.lstrip()) if content: indent = len(line) - content margin = min(margin, indent) # Remove indentation. if lines: lines[0] = lines[0].lstrip() if margin < sys.maxint: for i in range(1, len(lines)): lines[i] = lines[i][margin:] # Remove any trailing (but not leading!) blank lines. while lines and not lines[-1]: lines.pop() #while lines and not lines[0]: # lines.pop(0) return '\n'.join(lines) _IDENTIFIER_LIST_REGEXP = re.compile(r'^[\w.\*]+([\s,:;]\s*[\w.\*]+)*$') def _descr_to_identifiers(descr): """ Given a C{ParsedDocstring} that contains a list of identifiers, return a list of those identifiers. This is used by fields such as C{@group} and C{@sort}, which expect lists of identifiers as their values. To extract the identifiers, the docstring is first converted to plaintext, and then split. The plaintext content of the docstring must be a a list of identifiers, separated by spaces, commas, colons, or semicolons. @rtype: C{list} of C{string} @return: A list of the identifier names contained in C{descr}. @type descr: L{markup.ParsedDocstring} @param descr: A C{ParsedDocstring} containing a list of identifiers. @raise ValueError: If C{descr} does not contain a valid list of identifiers. """ idents = descr.to_plaintext(None).strip() idents = re.sub(r'\s+', ' ', idents) if not _IDENTIFIER_LIST_REGEXP.match(idents): raise ValueError, 'Bad Identifier list: %r' % idents rval = re.split('[:;, ] *', idents) return rval def _descr_to_docstring_field(arg, descr): tags = [s.lower() for s in re.split('[:;, ] *', arg)] descr = descr.to_plaintext(None).strip() args = re.split('[:;,] *', descr) if len(args) == 0 or len(args) > 3: raise ValueError, 'Wrong number of arguments' singular = args[0] if len(args) >= 2: plural = args[1] else: plural = None short = 0 if len(args) >= 3: if args[2] == 'short': short = 1 else: raise ValueError('Bad arg 2 (expected "short")') return DocstringField(tags, singular, plural, short) ###################################################################### #{ Function Signature Extraction ###################################################################### # [XX] todo: add optional type modifiers? _SIGNATURE_RE = re.compile( # Class name (for builtin methods) r'^\s*((?P\w+)\.)?' + # The function name (must match exactly) [XX] not anymore! r'(?P\w+)' + # The parameters r'\((?P(\s*\[?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?'+ r'(\s*\[?\s*,\s*\]?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?)*\]*)?)\s*\)' + # The return value (optional) r'(\s*(->)\s*(?P\S.*?))?'+ # The end marker r'\s*(\n|\s+(--|<=+>)\s+|$|\.\s+|\.\n)') """A regular expression that is used to extract signatures from docstrings.""" def parse_function_signature(func_doc, doc_source, docformat, parse_errors): """ Construct the signature for a builtin function or method from its docstring. If the docstring uses the standard convention of including a signature in the first line of the docstring (and formats that signature according to standard conventions), then it will be used to extract a signature. Otherwise, the signature will be set to a single varargs variable named C{"..."}. @param func_doc: The target object where to store parsed signature. Also container of the docstring to parse if doc_source is C{None} @type func_doc: L{RoutineDoc} @param doc_source: Contains the docstring to parse. If C{None}, parse L{func_doc} docstring instead @type doc_source: L{APIDoc} @rtype: C{None} """ if doc_source is None: doc_source = func_doc # If there's no docstring, then don't do anything. if not doc_source.docstring: return False m = _SIGNATURE_RE.match(doc_source.docstring) if m is None: return False # Do I want to be this strict? # Notice that __init__ must match the class name instead, if the signature # comes from the class docstring # if not (m.group('func') == func_doc.canonical_name[-1] or # '_'+m.group('func') == func_doc.canonical_name[-1]): # log.warning("Not extracting function signature from %s's " # "docstring, since the name doesn't match." % # func_doc.canonical_name) # return False params = m.group('params') rtype = m.group('return') selfparam = m.group('self') # Extract the parameters from the signature. func_doc.posargs = [] func_doc.vararg = None func_doc.kwarg = None if func_doc.posarg_defaults is UNKNOWN: func_doc.posarg_defaults = [] if params: # Figure out which parameters are optional. while '[' in params or ']' in params: m2 = re.match(r'(.*)\[([^\[\]]+)\](.*)', params) if not m2: return False (start, mid, end) = m2.groups() mid = re.sub(r'((,|^)\s*[\w\-\.]+)', r'\1=...', mid) params = start+mid+end params = re.sub(r'=...=' , r'=', params) for name in params.split(','): if '=' in name: (name, default_repr) = name.split('=',1) default = GenericValueDoc(parse_repr=default_repr) else: default = None name = name.strip() if name == '...': func_doc.vararg = '...' elif name.startswith('**'): func_doc.kwarg = name[2:] elif name.startswith('*'): func_doc.vararg = name[1:] else: func_doc.posargs.append(name) if len(func_doc.posarg_defaults) < len(func_doc.posargs): func_doc.posarg_defaults.append(default) elif default is not None: argnum = len(func_doc.posargs)-1 func_doc.posarg_defaults[argnum] = default # Extract the return type/value from the signature if rtype: func_doc.return_type = markup.parse(rtype, docformat, parse_errors, inline=True) # Add the self parameter, if it was specified. if selfparam: func_doc.posargs.insert(0, selfparam) func_doc.posarg_defaults.insert(0, None) # Remove the signature from the docstring. doc_source.docstring = doc_source.docstring[m.end():] # We found a signature. return True epydoc-3.0.1+dfsg/epydoc/compat.py0000644000175000017500000002072710654406441017331 0ustar pronovicpronovic# epydoc -- Backwards compatibility # # Copyright (C) 2005 Edward Loper # Author: Edward Loper # URL: # # $Id: util.py 956 2006-03-10 01:30:51Z edloper $ """ Backwards compatibility with previous versions of Python. This module provides backwards compatibility by defining several functions and classes that were not available in earlier versions of Python. Intented usage: >>> from epydoc.compat import * Currently, epydoc requires Python 2.3+. """ __docformat__ = 'epytext' ###################################################################### #{ New in Python 2.4 ###################################################################### # set try: set except NameError: try: from sets import Set as set, ImmutableSet as frozenset except ImportError: pass # use fallback, in the next section. # sorted try: sorted except NameError: def sorted(iterable, cmp=None, key=None, reverse=False): if key is None: elts = list(iterable) else: elts = [(key(v), v) for v in iterable] if reverse: elts.reverse() # stable sort. if cmp is None: elts.sort() else: elts.sort(cmp) if reverse: elts.reverse() if key is None: return elts else: return [v for (k,v) in elts] # reversed try: reversed except NameError: def reversed(iterable): elts = list(iterable) elts.reverse() return elts ###################################################################### #{ New in Python 2.3 ###################################################################### # Below is my initial attempt at backporting enough code that # epydoc 3 would run under python 2.2. However, I'm starting # to think that it's not worth the trouble. At the very least, # epydoc's current unicode handling still doesn't work under # 2.2 (after the backports below), since the 'xmlcharrefreplace' # error handler was introduced in python 2.3. # # basestring # try: # basestring # except NameError: # basestring = (str, unicode) # # sum # try: # sum # except NameError: # def _add(a,b): return a+b # def sum(vals): return reduce(_add, vals, 0) # # True & False # try: # True # except NameError: # True = 1 # False = 0 # # enumerate # try: # enumerate # except NameError: # def enumerate(iterable): # lst = list(iterable) # return zip(range(len(lst)), lst) # # set # try: # set # except NameError: # class set(dict): # def __init__(self, elts=()): # dict.__init__(self, [(e,1) for e in elts]) # def __repr__(self): # return 'set(%r)' % list(self) # def add(self, key): self[key] = 1 # def copy(self): # return set(dict.copy(self)) # def difference(self, other): # return set([v for v in self if v not in other]) # def difference_udpate(self, other): # newval = self.difference(other) # self.clear(); self.update(newval) # def discard(self, elt): # try: del self[elt] # except: pass # def intersection(self, other): # return self.copy().update(other) # def intersection_update(self, other): # newval = self.intersection(other) # self.clear(); self.update(newval) # def issubset(self, other): # for elt in self: # if elt not in other: return False # return True # def issuperset(self, other): # for elt in other: # if elt not in self: return False # return True # def pop(self): self.popitem()[0] # def remove(self, elt): del self[elt] # def symmetric_difference(self, other): # return set([v for v in list(self)+list(other) # if (v in self)^(v in other)]) # def symmatric_difference_update(self, other): # newval = self.symmetric_difference(other) # self.clear(); self.update(newval) # def union(self, other): # return set([v for v in list(self)+list(other) # if (v in self) or (v in other)]) # def union_update(self, other): # newval = self.union(other) # self.clear(); self.update(newval) # def update(self, other): # dict.update(self, set(other)) # # optparse module # try: # import optparse # except ImportError: # import new, sys, getopt # class _OptionVals: # def __init__(self, vals): self.__dict__.update(vals) # class OptionParser: # def __init__(self, usage=None, version=None): # self.usage = usage # self.version = version # self.shortops = ['h'] # self.longops = [] # self.option_specs = {} # self.defaults = {} # def fail(self, message, exitval=1): # print >>sys.stderr, message # system.exit(exitval) # def add_option_group(self, group): pass # def set_defaults(self, **defaults): # self.defaults = defaults.copy() # def parse_args(self): # try: # (opts, names) = getopt.getopt(sys.argv[1:], # ''.join(self.shortops), # self.longops) # except getopt.GetoptError, e: # self.fail(e) # options = self.defaults.copy() # for (opt,val) in opts: # if opt == '-h': # self.fail('No help available') # if opt not in self.option_specs: # self.fail('Unknown option %s' % opt) # (action, dest, const) = self.option_specs[opt] # if action == 'store': # options[dest] = val # elif action == 'store_const': # options[dest] = const # elif action == 'count': # options[dest] = options.get(dest,0)+1 # elif action == 'append': # options.setdefault(dest, []).append(val) # else: # self.fail('unsupported action: %s' % action) # for (action,dest,const) in self.option_specs.values(): # if dest not in options: # if action == 'count': options[dest] = 0 # elif action == 'append': options[dest] = [] # else: options[dest] = None # for name in names: # if name.startswith('-'): # self.fail('names must follow options') # return _OptionVals(options), names # class OptionGroup: # def __init__(self, optparser, name): # self.optparser = optparser # self.name = name # def add_option(self, *args, **kwargs): # action = 'store' # dest = None # const = None # for (key,val) in kwargs.items(): # if key == 'action': action = val # elif key == 'dest': dest = val # elif key == 'const': const = val # elif key in ('help', 'metavar'): pass # else: self.fail('unsupported: %s' % key) # if action not in ('store_const', 'store_true', 'store_false', # 'store', 'count', 'append'): # self.fail('unsupported action: %s' % action) # optparser = self.optparser # for arg in args: # if arg.startswith('--'): # optparser.longops.append(arg[2:]) # elif arg.startswith('-') and len(arg)==2: # optparser.shortops += arg[1] # if action in ('store', 'append'): # optparser.shortops += ':' # else: # self.fail('bad option name %s' % arg) # if action == 'store_true': # (action, const) = ('store_const', True) # if action == 'store_false': # (action, const) = ('store_const', False) # optparser.option_specs[arg] = (action, dest, const) # # Install a fake module. # optparse = new.module('optparse') # optparse.OptionParser = OptionParser # optparse.OptionGroup = OptionGroup # sys.modules['optparse'] = optparse # # Clean up # del OptionParser, OptionGroup epydoc-3.0.1+dfsg/epydoc/checker.py0000644000175000017500000003126210654406441017446 0ustar pronovicpronovic# # objdoc: epydoc documentation completeness checker # Edward Loper # # Created [01/30/01 05:18 PM] # $Id: checker.py 1366 2006-09-07 15:54:59Z edloper $ # """ Documentation completeness checker. This module defines a single class, C{DocChecker}, which can be used to check the that specified classes of objects are documented. """ __docformat__ = 'epytext en' ################################################## ## Imports ################################################## import re, sys, os.path, string from xml.dom.minidom import Text as _Text from epydoc.apidoc import * # The following methods may be undocumented: _NO_DOCS = ['__hash__', '__repr__', '__str__', '__cmp__'] # The following methods never need descriptions, authors, or # versions: _NO_BASIC = ['__hash__', '__repr__', '__str__', '__cmp__'] # The following methods never need return value descriptions. _NO_RETURN = ['__init__', '__hash__', '__repr__', '__str__', '__cmp__'] # The following methods don't need parameters documented: _NO_PARAM = ['__cmp__'] class DocChecker: """ Documentation completeness checker. C{DocChecker} can be used to check that specified classes of objects are documented. To check the documentation for a group of objects, you should create a C{DocChecker} from a L{DocIndex} that documents those objects; and then use the L{check} method to run specified checks on the objects' documentation. What checks are run, and what objects they are run on, are specified by the constants defined by C{DocChecker}. These constants are divided into three groups. - Type specifiers indicate what type of objects should be checked: L{MODULE}; L{CLASS}; L{FUNC}; L{VAR}; L{IVAR}; L{CVAR}; L{PARAM}; and L{RETURN}. - Public/private specifiers indicate whether public or private objects should be checked: L{PRIVATE}. - Check specifiers indicate what checks should be run on the objects: L{TYPE}; L{DESCR}; L{AUTHOR}; and L{VERSION}. The L{check} method is used to perform a check on the documentation. Its parameter is formed by or-ing together at least one value from each specifier group: >>> checker.check(DocChecker.MODULE | DocChecker.DESCR) To specify multiple values from a single group, simply or their values together: >>> checker.check(DocChecker.MODULE | DocChecker.CLASS | ... DocChecker.FUNC ) @group Types: MODULE, CLASS, FUNC, VAR, IVAR, CVAR, PARAM, RETURN, ALL_T @type MODULE: C{int} @cvar MODULE: Type specifier that indicates that the documentation of modules should be checked. @type CLASS: C{int} @cvar CLASS: Type specifier that indicates that the documentation of classes should be checked. @type FUNC: C{int} @cvar FUNC: Type specifier that indicates that the documentation of functions should be checked. @type VAR: C{int} @cvar VAR: Type specifier that indicates that the documentation of module variables should be checked. @type IVAR: C{int} @cvar IVAR: Type specifier that indicates that the documentation of instance variables should be checked. @type CVAR: C{int} @cvar CVAR: Type specifier that indicates that the documentation of class variables should be checked. @type PARAM: C{int} @cvar PARAM: Type specifier that indicates that the documentation of function and method parameters should be checked. @type RETURN: C{int} @cvar RETURN: Type specifier that indicates that the documentation of return values should be checked. @type ALL_T: C{int} @cvar ALL_T: Type specifier that indicates that the documentation of all objects should be checked. @group Checks: TYPE, AUTHOR, VERSION, DESCR, ALL_C @type TYPE: C{int} @cvar TYPE: Check specifier that indicates that every variable and parameter should have a C{@type} field. @type AUTHOR: C{int} @cvar AUTHOR: Check specifier that indicates that every object should have an C{author} field. @type VERSION: C{int} @cvar VERSION: Check specifier that indicates that every object should have a C{version} field. @type DESCR: C{int} @cvar DESCR: Check specifier that indicates that every object should have a description. @type ALL_C: C{int} @cvar ALL_C: Check specifier that indicates that all checks should be run. @group Publicity: PRIVATE @type PRIVATE: C{int} @cvar PRIVATE: Specifier that indicates that private objects should be checked. """ # Types MODULE = 1 CLASS = 2 FUNC = 4 VAR = 8 #IVAR = 16 #CVAR = 32 PARAM = 64 RETURN = 128 PROPERTY = 256 ALL_T = 1+2+4+8+16+32+64+128+256 # Checks TYPE = 256 AUTHOR = 1024 VERSION = 2048 DESCR = 4096 ALL_C = 256+512+1024+2048+4096 # Private/public PRIVATE = 16384 ALL = ALL_T + ALL_C + PRIVATE def __init__(self, docindex): """ Create a new C{DocChecker} that can be used to run checks on the documentation of the objects documented by C{docindex} @param docindex: A documentation map containing the documentation for the objects to be checked. @type docindex: L{Docindex} """ self._docindex = docindex # Initialize instance variables self._checks = 0 self._last_warn = None self._out = sys.stdout self._num_warnings = 0 def check(self, *check_sets): """ Run the specified checks on the documentation of the objects contained by this C{DocChecker}'s C{DocIndex}. Any errors found are printed to standard out. @param check_sets: The checks that should be run on the documentation. This value is constructed by or-ing together the specifiers that indicate which objects should be checked, and which checks should be run. See the L{module description} for more information. If no checks are specified, then a default set of checks will be run. @type check_sets: C{int} @return: True if no problems were found. @rtype: C{boolean} """ if not check_sets: check_sets = (DocChecker.MODULE | DocChecker.CLASS | DocChecker.FUNC | DocChecker.VAR | DocChecker.DESCR,) self._warnings = {} log.start_progress('Checking docs') for j, checks in enumerate(check_sets): self._check(checks) log.end_progress() for (warning, docs) in self._warnings.items(): docs = sorted(docs) docnames = '\n'.join([' - %s' % self._name(d) for d in docs]) log.warning('%s:\n%s' % (warning, docnames)) def _check(self, checks): self._checks = checks # Get the list of objects to check. valdocs = sorted(self._docindex.reachable_valdocs( imports=False, packages=False, bases=False, submodules=False, subclasses=False, private = (checks & DocChecker.PRIVATE))) docs = set() for d in valdocs: if not isinstance(d, GenericValueDoc): docs.add(d) for doc in valdocs: if isinstance(doc, NamespaceDoc): for d in doc.variables.values(): if isinstance(d.value, GenericValueDoc): docs.add(d) for i, doc in enumerate(sorted(docs)): if isinstance(doc, ModuleDoc): self._check_module(doc) elif isinstance(doc, ClassDoc): self._check_class(doc) elif isinstance(doc, RoutineDoc): self._check_func(doc) elif isinstance(doc, PropertyDoc): self._check_property(doc) elif isinstance(doc, VariableDoc): self._check_var(doc) else: log.error("Don't know how to check %r" % doc) def _name(self, doc): name = str(doc.canonical_name) if isinstance(doc, RoutineDoc): name += '()' return name def _check_basic(self, doc): """ Check the description, author, version, and see-also fields of C{doc}. This is used as a helper function by L{_check_module}, L{_check_class}, and L{_check_func}. @param doc: The documentation that should be checked. @type doc: L{APIDoc} @rtype: C{None} """ if ((self._checks & DocChecker.DESCR) and (doc.descr in (None, UNKNOWN))): if doc.docstring in (None, UNKNOWN): self.warning('Undocumented', doc) else: self.warning('No description', doc) if self._checks & DocChecker.AUTHOR: for tag, arg, descr in doc.metadata: if 'author' == tag: break else: self.warning('No authors', doc) if self._checks & DocChecker.VERSION: for tag, arg, descr in doc.metadata: if 'version' == tag: break else: self.warning('No version', doc) def _check_module(self, doc): """ Run checks on the module whose APIDoc is C{doc}. @param doc: The APIDoc of the module to check. @type doc: L{APIDoc} @rtype: C{None} """ if self._checks & DocChecker.MODULE: self._check_basic(doc) def _check_class(self, doc): """ Run checks on the class whose APIDoc is C{doc}. @param doc: The APIDoc of the class to check. @type doc: L{APIDoc} @rtype: C{None} """ if self._checks & DocChecker.CLASS: self._check_basic(doc) def _check_property(self, doc): if self._checks & DocChecker.PROPERTY: self._check_basic(doc) def _check_var(self, doc): """ Run checks on the variable whose documentation is C{var} and whose name is C{name}. @param doc: The documentation for the variable to check. @type doc: L{APIDoc} @rtype: C{None} """ if self._checks & DocChecker.VAR: if (self._checks & (DocChecker.DESCR|DocChecker.TYPE) and doc.descr in (None, UNKNOWN) and doc.type_descr in (None, UNKNOWN) and doc.docstring in (None, UNKNOWN)): self.warning('Undocumented', doc) else: if (self._checks & DocChecker.DESCR and doc.descr in (None, UNKNOWN)): self.warning('No description', doc) if (self._checks & DocChecker.TYPE and doc.type_descr in (None, UNKNOWN)): self.warning('No type information', doc) def _check_func(self, doc): """ Run checks on the function whose APIDoc is C{doc}. @param doc: The APIDoc of the function to check. @type doc: L{APIDoc} @rtype: C{None} """ name = doc.canonical_name if (self._checks & DocChecker.FUNC and doc.docstring in (None, UNKNOWN) and doc.canonical_name[-1] not in _NO_DOCS): self.warning('Undocumented', doc) return if (self._checks & DocChecker.FUNC and doc.canonical_name[-1] not in _NO_BASIC): self._check_basic(doc) if (self._checks & DocChecker.RETURN and doc.canonical_name[-1] not in _NO_RETURN): if (doc.return_type in (None, UNKNOWN) and doc.return_descr in (None, UNKNOWN)): self.warning('No return descr', doc) if (self._checks & DocChecker.PARAM and doc.canonical_name[-1] not in _NO_PARAM): if doc.arg_descrs in (None, UNKNOWN): self.warning('No argument info', doc) else: args_with_descr = [] for arg, descr in doc.arg_descrs: if isinstance(arg, basestring): args_with_descr.append(arg) else: args_with_descr += arg for posarg in doc.posargs: if (self._checks & DocChecker.DESCR and posarg not in args_with_descr): self.warning('Argument(s) not described', doc) if (self._checks & DocChecker.TYPE and posarg not in doc.arg_types): self.warning('Argument type(s) not described', doc) def warning(self, msg, doc): self._warnings.setdefault(msg,set()).add(doc) epydoc-3.0.1+dfsg/setup.py0000755000175000017500000000151110654406442015715 0ustar pronovicpronovic#! /usr/bin/env python # # Edward Loper's API Documentation Generation Tool # # Created [05/27/01 09:04 PM] # Edward Loper # from distutils.core import setup import re, sys, epydoc VERSION = str(epydoc.__version__) (AUTHOR, EMAIL) = re.match('^(.*?)\s*<(.*)>$', epydoc.__author__).groups() URL = epydoc.__url__ LICENSE = epydoc.__license__ if '--format=wininst' in sys.argv: SCRIPTS = ['scripts/epydoc.pyw', 'scripts/epydoc.py'] else: SCRIPTS = ['scripts/epydoc', 'scripts/epydocgui'] SCRIPTS.append('scripts/apirst2html.py') setup(name="epydoc", description="Edward Loper's API Documentation Generation Tool", version=VERSION, author=AUTHOR, author_email=EMAIL, license=LICENSE, url=URL, scripts=SCRIPTS, packages=['epydoc', 'epydoc.markup', 'epydoc.test', 'epydoc.docwriter']) epydoc-3.0.1+dfsg/doc/0002755000175000017500000000000012047475234014754 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/stylesheet.html0000644000175000017500000001712410750103050020015 0ustar pronovicpronovic Default Epydoc CSS Stylesheet

      Default Epydoc CSS Stylesheet

      Note: this is not up-to-date.

      /* Body color */ 
      body               { background: #ffffff; color: #000000; } 
       
      /* Tables */ 
      table.summary, table.details, table.index
                         { background: #e8f0f8; color: #000000; } 
      tr.summary, tr.details, tr.index 
                         { background: #70b0f0; color: #000000;  
                           text-align: left; font-size: 120%; } 
       
      /* Headings */
      h1.heading         { font-size: +140%; font-style: italic;
                           font-weight: bold; }
      h2.heading         { font-size: +125%; font-style: italic;
                           font-weight: bold; }
      h3.heading         { font-size: +110%; font-style: italic;
                           font-weight: normal; }
                           
      /* Base tree */
      pre.base-tree      { font-size: 80%; }
      
      /* Details Sections */
      table.func-details { background: #e8f0f8; color: #000000;
                           border: 2px groove #c0d0d0;
                           padding: 0 1em 0 1em; margin: 0.4em 0 0 0; }
      h3.func-detail     { background: transparent; color: #000000;
                           margin: 0 0 1em 0; }
      
      table.var-details  { background: #e8f0f8; color: #000000;
                           border: 2px groove #c0d0d0;
                           padding: 0 1em 0 1em; margin: 0.4em 0 0 0; }
      h3.var-details     { background: transparent; color: #000000;
                           margin: 0 0 1em 0; }
      
      /* Function signatures */
      .sig               { background: transparent; color: #000000;
                           font-weight: bold; }  
      .sig-name          { background: transparent; color: #006080; }  
      .sig-arg, .sig-kwarg, .sig-vararg
                         { background: transparent; color: #008060; }  
      .sig-default       { background: transparent; color: #602000; }  
      .summary-sig       { background: transparent; color: #000000; }  
      .summary-sig-name  { background: transparent; font-weight: bold; }  
      .summary-sig-arg, .summary-sig-kwarg, .summary-sig-vararg
                         { background: transparent; color: #008060; }  
      
      /* Doctest blocks */
      .pysrc             { background: transparent; color: #000000; }
      .pyprompt          { background: transparent; color: #003030;
                           font-weight: bold;}
      .pystring          { background: transparent; color: #006030; }
      .pycomment         { background: transparent; color: #003060; }
      .pykeyword         { background: transparent; color: #402000; }
      .pyoutput          { background: transparent; color: #404040; }
       
      /* Navigation bar */ 
      table.navbar       { background: #a0c0ff; color: #000000;
                           border: 2px groove #c0d0d0; }
      th.navbar          { background: #a0c0ff; color: #6090d0; font-size: 110% } 
      th.navselect       { background: #70b0ff; color: #000000; font-size: 110% } 
      
      /* Links */ 
      a:link             { background: transparent; color: #0000ff; }  
      a:visited          { background: transparent; color: #204080; }  
      a.navbar:link      { background: transparent; color: #0000ff; 
                           text-decoration: none; }  
      a.navbar:visited   { background: transparent; color: #204080; 
                           text-decoration: none; }  
      
      epydoc-3.0.1+dfsg/doc/relatedprojects.html0000644000175000017500000003273210750103050021020 0ustar pronovicpronovic Related Projects

      Related Projects

      1. Doc-sig

      Doc-sig is a Python special interest group dedicated to producing documentation and documentation tools for Python. Much of my work on epydoc was influenced by conversations on the doc-sig mailing list.

      2. Python API Extraction Tools

      Several tools have been created to extract API documentation from Python. This section describes the tools that I have looked at, and compares them to epydoc. If I left out any tools, please let me know.

      2.1. Pydoc

      Pydoc is the only widely accepted API documentation tool for Python. It became part of the standard library in Python 2.1. Pydoc defines three basic modes of operation:

      • The a command line interface that creates output that is similar to the manual pages shown by the unix man command. It can also be used to search for keywords, like the unix apropos command.
      • Pydoc can be used to create formatted HTML pages. For an example of the html output of pydoc, see the pydoc homepage, which was created using pydoc.
      • Pydoc provides interactive help from the Python interpreter, via the help function:
        >>> from pydoc import help
        
        >>> help(x_intercept)
        Help on function x_intercept in module __main__:
        
        x_intercept(m, b)
            Return the x intercept of the line y=m*x+b.  The x intercept of a
            line is the point at which it crosses the x axis (y=0).
        

      One limitation of pydoc (and perhaps one of the reasons that it was able to become widely accepted) is that it does make any assumptions about how docstrings are formatted; it simply displays them as they are, with a fixed-width font. As a result, no special formatting can be applied to the text; and there is no way to let pydoc know what parts of the docstring describe specific fields, like parameters or variables. On the other hand, this lack of assumptions about formatting guarantees that pydoc can be used with any Python code.

      Like epydoc, pydoc derives information about Python objects by using introspection. This allows pydoc to be used on both Python and builtin (C) modules; but it also means that pydoc does not have access to some types of information (such as where objects are imported from), and it means that pydoc can only document modules that can be safely imported.

      Pydoc fills a very useful niche, and I use it on a regular basis to check the documentation of Python objects. But for documenting my own projects, I prefer to use a tool that can make use of formatting conventions in the docstrings.

      2.2. HappyDoc

      Aside from pydoc, HappyDoc is probably the most widely used API documentation tool for Python. It is used by at least 5 major projects, including Numerical Python. For an example of the HTML output produced by happydoc, see the HappyDoc homepage, which was created using HappyDoc.

      HappyDoc is the most flexible API documentation tool currently available. It supports several different docstring markup languages, including StructuredText; StructuredTextNG; plain text; raw text; and MML. It can produce a wide variety of output formats, including HTML, text files, DocBook, and Dia.

      Unlike epydoc, HappyDoc derives information about Python objects by parsing the Python source files. This means that HappyDoc can be used to document modules that cannot be safely imported, and that it has access to some types of information that are difficult to retrieve via introspection. This also allows HappyDoc objects to be documented using comments as well as docstrings. However, since HappyDoc gets information about Python objects by parsing Python source files, it cannot be used on builtin (C) modules.

      I considered integrating epydoc with HappyDoc (as a docstring converter for epytext and a formatter for epydoc's html output), but I decided that it would be too difficult. In particular, it would require signifigant work to port epydoc's html output code, because of the differences in how epydoc and HappyDoc derive and store information about Python objects. Also, HappyDoc does not appear to have a mechanism for associating descriptions with specific fields (such as paremeters of a function). However, I may decided at some point to implement a docstring converter for epytext, since that would at least allow me to use HappyDoc to generate DocBook and pdf versions of API documentation.

      2.3. Docutils

      Docutils is a project to create a modular framework for Python API documentation generation. The project looks promising, but it is still under construction. Once it is completed, it may become the standard framework for Python API documentation tools. If it does, then I may decide to integrate epydoc with it.

      The markup language of choice for Docutils is reStructuredText. reStructuredText is a fairly powerful markup language, with some of the same goals as epytext. However, it is designed to be used for a wide variety of tasks, and some of its features may not be very useful for API documentation. The markup language itself is too complicated for my taste, using a wide variety of context-dependant rules to try to "guess" what you mean. In comparison, epytext is much simpler, with six simple block structure constructs, and one inline markup construct. If Docutils becomes the standard framework for API documentation generation, epytext might provide a simpler markup language for people who find reStructuredText too complex.

      Porting the epydoc HTML output system to Docutils may prove difficult, for some of the same reasons mentioned above for HappyDoc. However, if Docutils becomes the standard framework for API documentation tools, then I may try to port it.

      2.4. Pythondoc

      Pythondoc is a Python API documentation tool that uses StructuredText for markup, and can produce HTML and XML output. It uses XML as an intermediate representation, to simplify the addition of new output formats.

      2.5. Crystal

      Crystal is a Python API documentation tool that produces output that is similar to Javadoc. Its homepage includes a sample of the output it generates.

      2.6. Easydoc

      Easydoc is a Python API documentation tool based on htmltmpl. It uses an HTML-like markup language, similar to the language used by Javadoc; and produces HTML output.

      2.7. Teud

      Teud is a Python API documentation tool that does not apply any formatting to docstrings (like pydoc). It produces XML output, which can then be transformed to HTML using an XSLT stylesheet. Its homepage includes a sample of the output it generates.

      2.8. XIST

      XIST is an XML based extensible HTML generator written in Python. It can be used to produce API documentation in HTML.

      2.9. HTMLgen

      HTMLgen is a Python library for generating HTML documents. It can be used to produce API documentation; for an example of its output, see the HTMLgen Manual

      2.10. doc.py

      doc.py is a Python API documentation tool that is no longer under active development. It uses an unspecified markup langauge, and produces HTML output. For an example of its output, see its API documentation.

      3. API Extraction Tools for Other Languages

      3.1. Javadoc

      Javadoc is the standard API documentation tool for Java. It uses special comments to document classes, interfaces, methods, and variables. Its markup language consists of HTML, extended with a few special constructs such as fields. The javadoc program extracts the API documentation, and converts it into a set of HTML pages. For an example of the HTML output produced by javadoc, see the j2se 1.4 API specification.

      The use of HTML as a markup language for API documentation has two major disadvantages. First, HTML is quite verbose, which makes it inconvenient to write and read the documentation. Second, it means that the only supported output format is HTML; API documentation cannot be rendered in other formats, such as pdf.

      On the other hand, the use of HTML has some significant advantages. First, HTML is widely used and widely known, so most programmers don't need to learn a new markup language. Second, the use of HTML simplifies the construction of documentation formatting tools. And finally, HTML provides a great deal of freedom for including complex constructs in the API documentation, such as tables, charts, and images.

      Javadoc was the original inspiration for epydoc, and I adopted its use of fields. However, I decided that HTML was too verbose and complex of a markup language, and decided to create a simpler markup language instead.

      3.2. Doxygen

      Doxygen is an API documentation tool for for C++, C, Java, and IDL. It is the most commonly used API documentation tool for C and C++. It uses a fairly complex markup language, which can handle everything from lists to crossreferences to mathematical formulas. It can output the API documentation as HTML, LaTeX, Postscript, PDF, RTF, and Unix man pages. It also has a number of advanced features that are not supported by any other API documentation tools that I know of, such as producing call graphs using dot; and rendering LaTeX-style mathematical formulas.

      3.3. POD

      POD (Plain Old Documentation) is the standard API documentation tool for Perl. POD defines a simple low-level markup language that integrates well with the Perl parser. Tools exist to convert POD documentation into a variety of formats, including HTML and man pages. For an example of the HTML output produced for POD, see the Perldoc POD Page

      The inline markup construct (x{...}) used by epydoc was partially inspired by the POD inline markup construct (x<...>). However, I decided to use curly braces instead of angle braces, because it significantly reduces the need for escaping. A matching pair of curly braces is only interpreted as markup if the left brace is immediately preceeded by a capital letter; thus, you only need to use escaping if:

      1. You want to include a single (un-matched) curly brace.
      2. You want to preceed a matched pair of curly braces with a capital letter.

      Note that there is no valid Python expression where a pair of matched curly braces is immediately preceeded by a capital letter (except within string literals); so case (2) is unlikely to cause any problems.

      3.4. Other Tools

      The Doxygen page includes a fairly extensive list of API documentation extraction tools.

      epydoc-3.0.1+dfsg/doc/epytext.html0000644000175000017500000011617110750103047017336 0ustar pronovicpronovic The Epytext Markup Language

      The Epytext Markup Language

      1. Overview

      Epytext is a lightweight markup language for Python docstrings. The epytext markup language is used by epydoc to parse docstrings and create structured API documentation. Epytext markup is broken up into the following categories:

      • Block Structure divides the docstring into nested blocks of text, such as paragraphs and lists.
        • Basic Blocks are the basic unit of block structure.
        • Hierarchical blocks represent the nesting structure of the docstring.
      • Inline Markup marks regions of text within a basic block with properties, such as italics and hyperlinks.

      2. Block Structure

      Block structure is encoded using indentation, blank lines, and a handful of special character sequences.

      • Indentation is used to encode the nesting structure of hierarchical blocks. The indentation of a line is defined as the number of leading spaces on that line; and the indentation of a block is typically the indentation of its first line.
      • Blank lines are used to separate blocks. A blank line is a line that only contains whitespace.
      • Special character sequences are used to mark the beginnings of some blocks. For example, "-" is used as a bullet for unordered list items, and ">>>" is used to mark doctest blocks.

      The following sections describe how to use each type of block structure.

      2.1. Paragraphs

      A paragraph is the simplest type of basic block. It consists of one or more lines of text. Paragraphs must be left justified (i.e., every line must have the same indentation). The following example illustrates how paragraphs can be used:

      Docstring InputRendered Output
      def example():
          """
          This is a paragraph.  Paragraphs can
          span multiple lines, and can contain
          I{inline markup}.
          
      
          This is another paragraph.  Paragraphs
          are separated by blank lines.
          """
          [...]
      

      This is a paragraph. Paragraphs can span multiple lines, and contain inline markup.

      This is another paragraph. Paragraphs are separated from each other by blank lines.

      2.2. Lists

      Epytext supports both ordered and unordered lists. A list consists of one or more consecutive list items of the same type (ordered or unordered), with the same indentation. Each list item is marked by a bullet. The bullet for unordered list items is a single dash character ("-"). Bullets for ordered list items consist of a series of numbers followed by periods, such as "12." or "1.2.8.".

      List items typically consist of a bullet followed by a space and a single paragraph. The paragraph may be indented more than the list item's bullet; often, the paragraph is intended two or three characters, so that its left margin lines up with the right side of the bullet. The following example illustrates a simple ordered list.

      Docstring InputRendered Output
      def example():
          """
          1. This is an ordered list item.
      
          2. This is a another ordered list
          item.
      
          3. This is a third list item.  Note that
             the paragraph may be indented more
             than the bullet.
          """
          [...]
      
      1. This is an ordered list item.
      2. This is another ordered list item.
      3. This is a third list item. Note that the paragraph may be indented more than the bullet.

      List items can contain more than one paragraph; and they can also contain sublists, literal blocks, and doctest blocks. All of the blocks contained by a list item must all have equal indentation, and that indentation must be greater than or equal to the indentation of the list item's bullet. If the first contained block is a paragraph, it may appear on the same line as the bullet, separated from the bullet by one or more spaces, as shown in the previous example. All other block types must follow on separate lines.

      Every list must be separated from surrounding blocks by indentation:

      Docstring InputRendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
            2. This a second list
               item.
                 - This is a sublist
          """
          [...]
      
      This is a paragraph.
      1. This is a list item.
      2. This is a second list item.
        • This is a sublist.

      Note that sublists must be separated from the blocks in their parent list item by indentation. In particular, the following docstring generates an error, since the sublist is not separated from the paragraph in its parent list item by indentation:

      Docstring InputRendered Output
      def example():
          """
          1. This is a list item.  Its
             paragraph is indented 7 spaces.
             - This is a sublist.  It is
               indented 7 spaces.
          """
          [...]
      
      L5: Error: Lists must be indented.

      The following example illustrates how lists can be used:

      Docstring InputRendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
              - This is a sublist.
              - The sublist contains two
                items.
                  - The second item of the 
                    sublist has its own sublist.
      
            2. This list item contains two
               paragraphs and a doctest block.
      
               >>> print 'This is a doctest block'
               This is a doctest block
      
               This is the second paragraph.
          """
          [...]
      
      This is a paragraph.
      1. This is a list item.
        • This is a sublist.
        • The sublist contains two items.
          • The second item of the sublist has its own own sublist.
      2. This list item contains two paragraphs and a doctest block.
        >>> print 'This is a doctest block'
        This is a doctest block

        This is the second paragraph.

      Epytext will treat any line that begins with a bullet as a list item. If you want to include bullet-like text in a paragraph, then you must either ensure that it is not at the beginning of the line, or use escaping to prevent epytext from treating it as markup:

      Docstring InputRendered Output
      def example():
          """
          This sentence ends with the number
          1.  Epytext can't tell if the "1."
          is a bullet or part of the paragraph,
          so it generates an error.
          """
          [...]
      
      L4: Error: Lists must be indented.
      def example():
          """
          This sentence ends with the number 1.
      
          This sentence ends with the number
          E{1}.
          """
          [...]
      
      This sentence ends with the number 1.

      This sentence ends with the number 1.

      2.3. Sections

      A section consists of a heading followed by one or more child blocks.

      • The heading is a single underlined line of text. Top-level section headings are underlined with the "=" character; subsection headings are underlined with the "-" character; and subsubsection headings are underlined with the "~" character. The length of the underline must exactly match the length of the heading.
      • The child blocks can be paragraphs, lists, literal blocks, doctest blocks, or sections. Each child must have equal indentation, and that indentation must be greater than or equal to the heading's indentation.

      The following example illustrates how sections can be used:

      Docstring InputRendered Output
      def example():
          """
          This paragraph is not in any section.
      
          Section 1
          =========
            This is a paragraph in section 1.
      
            Section 1.1
            -----------
            This is a paragraph in section 1.1.
      
          Section 2
          =========
            This is a paragraph in section 2.
          """
          [...]
      
      Section 1
      This is a paragraph in section 1.

      Section 1.1
      This is a paragraph in section 1.1.

      Section 2
      This is a paragraph in section 2.

      2.4. Literal Blocks

      Literal blocks are used to represent "preformatted" text. Everything within a literal block should be displayed exactly as it appears in plaintext. In particular:

      • Spaces and newlines are preserved.
      • Text is shown in a monospaced font.
      • Inline markup is not detected.

      Literal blocks are introduced by paragraphs ending in the special sequence "::". Literal blocks end at the first line whose indentation is equal to or less than that of the paragraph that introduces them. The following example shows how literal blocks can be used:

      Docstring InputRendered Output
      def example():
          """
          The following is a literal block::
          
              Literal /
                     / Block
      
          This is a paragraph following the
          literal block.
          """
          [...]
      

      The following is a literal block:

          Literal /
                 / Block
      

      This is a paragraph following the literal block.

      Literal blocks are indented relative to the paragraphs that introduce them; for example, in the previous example, the word "Literal" is displayed with four leading spaces, not eight. Also, note that the double colon ("::") that introduces the literal block is rendered as a single colon.

      2.5. Doctest Blocks

      Doctest blocks contain examples consisting of Python expressions and their output. Doctest blocks can be used by the doctest module to test the documented object. Doctest blocks begin with the special sequence ">>>". Doctest blocks are delimited from surrounding blocks by blank lines. Doctest blocks may not contain blank lines. The following example shows how doctest blocks can be used:

      Docstring InputRendered Output
      def example():
          """
          The following is a doctest block:
          
              >>> print (1+3,
              ...        3+5)
              (4, 8)
              >>> 'a-b-c-d-e'.split('-')
              ['a', 'b', 'c', 'd', 'e']
      
          This is a paragraph following the
          doctest block.
          """
          [...]
      

      The following is a doctest block:

      >>> print (1+3,
      ...        3+5)
      (4, 8)
      >>> 'a-b-c-d-e'.split('-')
      ['a', 'b', 'c', 'd', 'e']
      

      This is a paragraph following the doctest block.

      2.6. Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field is marked by a field tag, which consist of an at sign ("@") followed by a field name, optionally followed by a space and a field argument, followed by a colon (":"). For example, "@return:" and "@param x:" are field tags.

      Fields can contain paragraphs, lists, literal blocks, and doctest blocks. All of the blocks contained by a field must all have equal indentation, and that indentation must be greater than or equal to the indentation of the field's tag. If the first contained block is a paragraph, it may appear on the same line as the field tag, separated from the field tag by one or more spaces. All other block types must follow on separate lines.

      Fields must be placed at the end of the docstring, after the description of the object. Fields may be included in any order.

      Fields do not need to be separated from other blocks by a blank line. Any line that begins with a field tag followed by a space or newline is considered a field.

      The following example illustrates how fields can be used:

      Docstring InputRendered Output
      def example():
          """
          @param x: This is a description of
              the parameter x to a function.
              Note that the description is
              indented four spaces.
          @type x: This is a description of
              x's type.
          @return: This is a description of
              the function's return value.
      
              It contains two paragraphs.
          """
          [...]
      
      Parameters:
      x - This is a description of the parameter x to a function. Note that the description is indented four spaces.
                 (type=This is a description of x's type.)
      Returns:
      This is a description of the function's return value.

      It contains two paragraphs.

      For a list of the fields that are supported by epydoc, see the epydoc fields page.

      3. Inline Markup

      Inline markup has the form "x{...}", where "x" is a single capital letter that specifies how the text between the braces should be rendered. Inline markup is recognized within paragraphs and section headings. It is not recognized within literal and doctest blocks. Inline markup can contain multiple words, and can span multiple lines. Inline markup may be nested.

      A matching pair of curly braces is only interpreted as inline markup if the left brace is immediately preceeded by a capital letter. So in most cases, you can use curly braces in your text without any form of escaping. However, you do need to escape curly braces when:

      1. You want to include a single (un-matched) curly brace.
      2. You want to preceed a matched pair of curly braces with a capital letter.

      Note that there is no valid Python expression where a pair of matched curly braces is immediately preceeded by a capital letter (except within string literals). In particular, you never need to escape braces when writing Python dictionaries. See section 3.5 for a discussion of escaping.

      3.1. Basic Inline Markup

      Epytext defines four types of inline markup that specify how text should be displayed:

      • I{...}: Italicized text.
      • B{...}: Bold-faced text.
      • C{...}: Source code or a Python identifier.
      • M{...}: A mathematical expression.

      By default, source code is rendered in a fixed width font; and mathematical expressions are rendered in italics. But those defaults may be changed by modifying the CSS stylesheet. The following example illustrates how the four basic markup types can be used:

      Docstring InputRendered Output
      def example():
          """
          I{B{Inline markup} may be nested; and
          it may span} multiple lines.
      
            - I{Italicized text}
            - B{Bold-faced text}
            - C{Source code}
            - M{Math}
      
          Without the capital letter, matching
          braces are not interpreted as markup:
          C{my_dict={1:2, 3:4}}.
          """
          [...]
      
      Inline markup may be nested; and it may span multiple lines.
      • Italicized text
      • Bold-faced text
      • Source code
      • Math: m*x+b
      Without the capital letter, matching braces are not interpreted as markup: my_dict={1:2, 3:4}.

      3.2. URLs

      The inline markup construct "U{text<url>}" is used to create links to external URLs and URIs. "Text" is the text that should be displayed for the link, and "url" is the target of the link. If you wish to use the URL as the text for the link, you can simply write "U{url}". Whitespace within URL targets is ignored. In particular, URL targets may be split over multiple lines. The following example illustrates how URLs can be used:

      Docstring InputRendered Output
      def example():
          """
          - U{www.python.org}
          - U{http://www.python.org}
          - U{The epydoc homepage<http://
            epydoc.sourceforge.net>}
          - U{The B{I{Python}} homepage
            <www.python.org>}
          - U{Edward Loper<mailto:edloper@
            gradient.cis.upenn.edu>}
          """
          [...]
      

      3.3. Documentation Crossreference Links

      The inline markup construct "L{text<object>}" is used to create links to the documentation for other Python objects. "Text" is the text that should be displayed for the link, and "object" is the name of the Python object that should be linked to. If you wish to use the name of the Python object as the text for the link, you can simply write "L{object}". Whitespace within object names is ignored. In particular, object names may be split over multiple lines. The following example illustrates how documentation crossreference links can be used:

      Docstring InputRendered Output
      def example():
          """
          - L{x_transform}
          - L{search<re.search>}
          - L{The I{x-transform} function
            <x_transform>}
          """
          [...]
      

      In order to find the object that corresponds to a given name, epydoc checks the following locations, in order:

      1. If the link is made from a class or method docstring, then epydoc checks for a method, instance variable, or class variable with the given name.
      2. Next, epydoc looks for an object with the given name in the current module.
      3. Epydoc then tries to import the given name as a module. If the current module is contained in a package, then epydoc will also try importing the given name from all packages containing the current module.
      4. Finally, epydoc tries to divide the given name into a module name and an object name, and to import the object from the module. If the current module is contained in a package, then epydoc will also try importing the module name from all packages containing the current module.

      If no object is found that corresponds with the given name, then epydoc issues a warning.

      3.4. Indexed Terms

      Epydoc automatically creates an index of term definitions for the API documentation. The inline markup construct "X{...}" is used to mark terms for inclusion in the index. The term itself will be italicized; and a link will be created from the index page to the location of the term in the text. The following example illustrates how index terms can be used:

      Docstring InputRendered Output
      def example():
          """
          An X{index term} is a term that
          should be included in the index.
          """
          [...]
      
      An index term is a term that should be included in the index.
      Index
      index term example
      x intercept x_intercept
      y intercept x_intercept

      3.5. Symbols

      Symbols are used to insert special characters in your documentation. A symbol has the form "S{code}", where code is a symbol code that specifies what character should be produced. The following example illustrates how symbols can be used to generate special characters:

      Docstring InputRendered Output
      def example():
          """
          Symbols can be used in equations:
            - S{sum}S{alpha}/x S{<=} S{beta}
      
          S{<-} and S{larr} both give left
          arrows.  Some other arrows are
          S{rarr}, S{uarr}, and S{darr}.
          """
          [...]
      

      Symbols can be used in equations:

      • ∑α/x ≤ β

      ← and ← both give left arrows. Some other arrows are →, ↑, and ↓.

      Although symbols can be quite useful, you should keep in mind that they can make it harder to read your docstring in plaintext. In general, symbols should be used sparingly. For a complete list of the symbols that are currently supported, see the reference documentation for epydoc.epytext.SYMBOLS.

      3.6. Escaping

      Escaping is used to write text that would otherwise be interpreted as epytext markup. Epytext was carefully constructed to minimize the need for this type of escaping; but sometimes, it is unavoidable. Escaped text has the form "E{code}", where code is an escape code that specifies what character should be produced. If the escape code is a single character (other than "{" or "}"), then that character is produced. For example, to begin a paragraph with a dash (which would normally signal a list item), write "E{-}". In addition, two special escape codes are defined: "E{lb}" produces a left curly brace ("{"); and "E{rb}" produces a right curly brace ("}"). The following example illustrates how escaping can be used:

      Docstring InputRendered Output
      def example():
          """
          This paragraph ends with two
          colons, but does not introduce
          a literal blockE{:}E{:}
      
          E{-} This is not a list item.
      
          Escapes can be used to write
          unmatched curly braces:
          E{rb}E{lb}
          """
          [...]
      

      This paragraph ends with two colons, but does not introduce a literal block::

      - This is not a list item.

      Escapes can be used to write unmatched curly braces: }{

      3.7. Graphs

      The inline markup construct "G{graphtype args...}" is used to insert automatically generated graphs. The following graphs generation constructions are currently defines:

      MarkupDescription
      G{classtree classes...}
      Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed.
      G{packagetree modules...}
      Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed.
      G{impotgraph modules...}
      Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed.
      G{callgraph functions...}
      Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed.

      4. Characters

      4.1. Valid Characters

      Valid characters for an epytext docstring are space ("\040"); newline ("\012"); and any letter, digit, or punctuation, as defined by the current locale. Control characters ("\000"-"\010" and "\013"-"\037") are not valid content characters. Tabs ("\011") are expanded to spaces, using the same algorithm used by the Python parser. Carridge-return/newline pairs ("\015\012") are converted to newlines.

      4.2. Content Characters

      Characters in a docstring that are not involved in markup are called content characters. Content characters are always displayed as-is. In particular, HTML codes are not passed through. For example, consider the following example:

      Docstring InputRendered Output
      def example():
          """
          <B>test</B>
          """
          [...]
      
      <B>test</B>

      The docstring is rendered as "<B>test</B>", and not as the word "test" in bold face.

      4.3. Spaces and Newlines

      In general, spaces and newlines within docstrings are treated as soft spaces. In other words, sequences of spaces and newlines (that do not contain a blank line) are rendered as a single space, and words may wrapped at spaces. However, within literal blocks and doctest blocks, spaces and newlines are preserved, and no word-wrapping occurs; and within URL targets and documentation link targets, whitespace is ignored.

      5. Warnings and Errors

      If epydoc encounters an error while processing a docstring, it issues a warning message that describes the error, and attempts to continue generating documentation. Errors related to epytext are divided into three categories:

      • Epytext Warnings are caused by epytext docstrings that contain questionable or suspicious markup. Epytext warnings do not prevent the docstring in question from being parsed.
      • Field Warnings are caused by epytext docstrings containing invalid fields. The contents of the invalid field are generally ignored.
      • Epytext Errors are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring.

      The following sections list and describe the warning messages that epydoc can generate. They are intended as a reference resource, which you can search for more information and possible causes if you encounter an error and do not understand it. These descriptions are also available in the epydoc(1) man page.

      5.1. Epytext Warnings

      • Possible mal-formatted field item.
        Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (":") is not included in the field tag.
      • Possible heading typo.
        Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading.

      5.2. Field Warnings

      • @param for unknown parameter param.
        A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      • tag did not expect an argument.
        The field tag tag was used with an argument, but it does not take one.
      • tag expected an argument.
        The field tag tag was used without an argument, but it requires one.
      • @type for unknown parameter param.
        A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      • @type for unknown variable var.
        A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name.
      • Unknown field tag tag.
        A docstring contains a field with the unknown tag tag.
      • Redefinition of field.
        Multiple field tags define the value of field in the same docstring, but field can only take a single value.

      5.3. Epytext Errors

      • Bad link target.
        The target specified for an inline link contruction (L{...}) is not well-formed. Link targets must be valid python identifiers.
      • Bad uri target.
        The target specified for an inline uri contruction (U{...}) is not well-formed. This typically occurs if inline markup is nested inside the URI target.
      • Fields must be at the top level.
        The list of fields (@param, etc.) is contained by some other block structure (such as a list or a section).
      • Fields must be the final elements in an epytext string.
        The list of fields (@param, etc.) is not at the end of a docstring.
      • Headings must occur at top level.
        The heading is contianed in some other block structure (such as a list).
      • Improper doctest block indentation.
        The doctest block dedents past the indentation of its initial prompt line.
      • Improper heading indentation.
        The heading for a section is not left-aligned with the paragraphs in the section that contains it.
      • Improper paragraph indentation.
        The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext.
      • Invalid escape.
        An unknown escape sequence was used with the inline escape construction (E{...}).
      • Lists must be indented.
        An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet.
      • Unbalanced '{'.
        The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      • Unbalanced '}'.
        The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      • Unknown inline markup tag.
        An unknown tag was used with the inline markup construction (x{...}).
      • Wrong underline character for heading.
        The underline character used for this section heading does not indicate an appopriate section level. The "=" character should be used to underline sections; "-" for subsections; and "~" for subsubsections.
      epydoc-3.0.1+dfsg/doc/docstrings.html0000644000175000017500000000662410750103047020014 0ustar pronovicpronovic Python Docstrings

      Python Docstrings

      Python documentation strings (or docstrings) provide a convenient way of associating documentation with Python modules, functions, classes, and methods. An object's docsting is defined by including a string constant as the first statement in the object's definition. For example, the following function defines a docstring:

      def x_intercept(m, b):
          """
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).
          """
          return -b/m
      

      Docstrings can be accessed from the interpreter and from Python programs using the "__doc__" attribute:

      >>> print x_intercept.__doc__
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).
      

      The pydoc module, which became part of the standard library in Python 2.1, can be used to display information about a Python object, including its docstring:

      >>> from pydoc import help
      
      >>> help(x_intercept)
      Help on function x_intercept in module __main__:
      
      x_intercept(m, b)
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).
      

      For more information about Python docstrings, see the Python Tutorial or the Oreilly Network article Python Documentation Tips and Tricks.

      epydoc-3.0.1+dfsg/doc/installing.html0000644000175000017500000002244110750103047017774 0ustar pronovicpronovic Installing Epydoc

      Installing Epydoc

      Downloading Epydoc

      Epydoc can be downloaded from the SourceForge download page. Epydoc is available in five formats:

      • RPM (.noarch.rpm)
      • Windows installer (.win32.exe)
      • Source install (.tar.gz)
      • Source install (.zip)
      • Source RPM (.src.rpm)

      If you are installing on RedHat, I recommend that you use the RPM file. If you are installing on Windows, I recommended that you use the windows installer. Otherwise, you should use one of the source install files.

      Getting Epydoc from Subversion

      If you wish to keep up on the latest developments, you can get the latest version of epydoc from the subversion repository:

      [/home/edloper]$ svn co https://epydoc.svn.sourceforge.net/svnroot/epydoc/trunk/epydoc epydoc
      [/home/edloper]$ ls epydoc
      Makefile  doc  man  sandbox  src
      

      This will create a directory named epydoc containing the latest version of epydoc. The epydoc package itself is in epydoc/src/epydoc (so adding epydoc/src to your PYTHONPATH will let you use it). You should periodically update your copy of the subversion repository, to make sure you have all the latest changes:

      [/home/edloper/epydoc]$ svn up
      

      You can browse the subversion repository here.

      Installing from the RPM File

      1. Download the RPM file to a directory of your choice.
      2. Use rpm to install the new package.
        [/tmp]$ su
        Password:
        [/tmp]# rpm -i epydoc-3.0.1.noarch.rpm
        
      3. Once epydoc is installed, you can delete the RPM file.
        [/tmp]# rm epydoc-3.0.1.rpm
        

      Installing from the Windows Installer

      1. Download and run epydoc-3.0.1.win32.exe.
      2. Follow the on-screen instructions. Epydoc will be installed in the epydoc subdirectory of your Python installation directory (typically C:\Python23\).
      3. The windows installer creates two scripts in the Scripts subdirectory of your Python installation directory: epydoc.pyw opens the graphical user interface, and epydoc.py calls the command line interface. If you'd like, you can create shortcuts from these scripts to more convenient locations (such as your desktop or start menu).
      4. Once epydoc is installed, you can delete epydoc-3.0.1.win32.exe.

      Installing from the Source Distribution (using make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.
        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use "make install" in the eydoc-3.0.1/ directory to install epydoc.
        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# make install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        
      3. If you'd like to keep a local copy of the documentation, then use "make installdocs". By default, this will install the documentation to /usr/share/doc/ and the man pages to /usr/share/man/. If you would prefer to install documentation to different directories (such as /usr/lib/doc), then edit the MAN and DOC variables at the top of Makefile before running "make installdocs".
        [/tmp/epydoc-3.0.1]# make installdocs
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.
        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      Installing from the Source Distribution (without make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.
        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use the setup.py script in the eydoc-3.0.1/ directory to install epydoc.
        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# python setup.py install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]#
        
      3. If you'd like to keep a local copy of the documentation, then copy it to a permanant location, such as /usr/share/doc/. You may also want to copy the man pages to a permanant location, such as /usr/share/man/.
        [/tmp]# cp -r epydoc-3.0.1/doc/ /usr/share/doc/epydoc/
        [/tmp]# cp epydoc-3.0.1/man/* /usr/share/man/
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.
        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      Installing on Debian

      Epydoc 2.1 is available as a testing debian package (python-epydoc). The epydoc documentation is also available as a package (epydoc-doc).

      epydoc-3.0.1+dfsg/doc/epydoc_guiconfig.png0000644000175000017500000005210010750103047020760 0ustar pronovicpronovic‰PNG  IHDRJ3ù4+tEXtCreation TimeThu 6 Apr 2006 18:13:29 -0500ÇÎâtIMEÖwS˜g pHYsttÞfxgAMA± üaS˜IDATxÚíÝM¨&Ù™Øù(;·À¨á&¤¥•»‘%¼)Á ´`VãM‹^¤/chš™ð¾•³i©­ò*ëö€MÙ`Ú›; c¤Y ’W]^ ¨nº*ZZU”º º /t‚&î¬S'ÏÇsžó'âÿ£ÈŠoĉñ~=ïsNœ3 ½öÝù×Ï?¿ýãõa`r¶PX`æZøo|øo¿÷ÚÛøço|åîgŸ>î Ëù—ù—ù—ù—¿ü÷äÿý÷îŒÑÓã'¿¼~q=à ϯŸ/ž]ÿú—ãòß[»2[GÀpÇùû“Ÿü±~ç¯ÿþ¿^»þ WQÇ2»øÜ€éÙÕ³qÝõ‹ë“;'ËáúÎpòâz¸srýb8¹éýt}}çää¶ÝžX‹|øñã³?ù¿ÚåòOÿhž7/Ö¸úôêäÅÉmP1œ ××ã?ÃõÉpr=Œ1ÆÉÍ/ê(T®®®ä?»þì“7äØæŽ¿âéÕÓßû§¿wùŸ/gº:  oãtÖòÇØèé§OÏþð죿ü(¶Í[ÿø­÷ÿÏ÷¿üû6PyöìÙ·ÿ§oÇvùùÿ÷óWŽrçdÜåw¾ù;þC£§óô{¿ÿ½àC¶;ÁµÿÇã³ÿõŒ˜ €-»xôápüä¿ýrŽÂÿ蟼½ÌYÑRòÑ\c˜eF&Z=~üøÍ7ߌíx'ö1›÷Ü–>ùÉøñÕÉðüzxýíoœ~ôñÕ¿øë¿úÅÕ‡¿z<>4ýùþùpÚøüÞþÖ7gÜlê»óý?xû;ßü·¾qúáÇOnnt™ ¦?ÇÍÆ’Ç?úÕUðQMsÞw~÷;ü·b~÷Ÿ~7öP0'Ë<Oÿ^þ§Ë)62ÑÒOöÓ7þáB%ï3°m¯ÿþïþ¶3ÙMi_†/¿z<ýy=<7Ó·­øÆwÞþF ×âÄCÓfc\58Lþ£Jïþé»±‡>ûÛÏä8&‹‰™ÎþùÙ{öÞ;ÿêi}2Zä€i f`ÃÎïß´š½÷/¹œ>~üÁ/®Þ<=yó·îš éýG~ÿþÛc”3…Y¿ÿ»oMñÍÅ£nKûÎðEÒhÜ~Œ„¾ÿíW÷Û’oRJSœ4EHSá_S·ª&Þû³÷‚˲;šÈ3°AB§ïÇŸ>ú9Æç­oœ~çö–±oóÍiÍ«›<ÿðvÇ»_9‰wjÝ˟ʱMÍs œ»î˜s<ý›§&·4Üæ™~ü“ßý­»Éµ#}“g`{žÇr9w¿r“Czë¹=Šn©¯nÚÑ>Ù½éé§Ïì N†×§½Nî¼>D¼ýÞ nï¾Aö=q&·4®ùìo?Kî«Ê0MÈ3°1áNß7î çðëáù”Fúðã—i¤qã7¿zÓ«éÿ·—=–œÝ¿ýÍÓëa8û_¾õf$ïb²S~á£o}ótztŒœÆåù½t$“LcTd¢¥¿øÙ_¼þ_ÿñO~<­ù½ïþ^²'SFÀ43°%¦Ó÷àÝÃ?uÁž|ôñ•ÝîfwN²×_<úà¶÷›o}#<ќڷ™§GßþÆ›¦K“H5çDHBÄsýâz4FEÓŸcœ4FKãÂÝߺûÓŸýtZ?–&ß+—0 ÄLô`HiQé¯~ñJÀd:'}øñ•Ýgº~ßîõr$§axÜÀÅî<êDim)om›œÜ9MËNT4.›˜©d¦¬z€…Åæˆ5>øð—ÿñ¿†ÇÈ6“üÛÙn†°î˜óÉ$w_ÑÛGušb¦ä8L7¾?{q=¼ÿÿüùÍ¿7]¢†¿žÿÝóç7 ·ÿŽËá5/n£Îcðùü¶Ö°æpk¶PÖ°†5¬yåséÖü?Šmo:=ýôz¸]³Ñí–·‘À’k®ŸþͳD°aþ­Þåääà.oXëíÚ^{ûÿüêó«áóç·\¿>œ°À ú…ávníT†X`…v ·Ÿð/ž]ÿú—Ï~õÁMÀôìógŸ={|û¹?|ñÀ ,(† ÔX`…^\w†)`ºéÃô•Ó7Ÿþâg,ן>>ùêM æk¿ùÍoÖ® Àv½öÚkÚ‘¾èâáÅ`†¸zrµv}¶åòÑË'É0$0$0$0$0$0$0$0$ÜÑlt÷kwƒëŸþúéôиЪBþ±P@0M– \Ì±Æøiü˜ ¬(#`²Kvr¨yˆcÑ,û ^:pÍú0™ÅŽi–aRPKGF†É„# $r²’U$–À¬÷aj•ã!c¶£°SLÛdÏÔ9‰Nß`]³ŒÃ4E93Õ˜´XX³€É4¢ÍtÚ)ŸlXØk¿ùÍoÆÿ]=¹Z»&Ûrùèrü÷ÿãt¦`ØLi¡¹ÄXK:`Ze€o€í`ò]€&€&€&€&€&€&€&€„—WN#Àw“aºxx±v5¶ë5f#ÜýÚ]ú0$¼ìÃtzïtíšlËÕ“«i @€ÝÉûŽý€ £ŽÌ@€ @@ÂØ e Àqvÿ,¸ž ûû”„€itþà|íšØ¡›#v@ø”»S¼'€ã¸|t™ ‰ø¸Ð¯ä§}˜˜˜˜îè7½ûµ»ã¿Oý4¹R¿{A9eåϱ㬶Y+@oz ÛÊ^Ïc9˼L…+?ˆxÛ»”0@ÿ÷Õ*ÁDò¸Îï“ÜŸ+IÀdLöGƒó ÒþSøè±×Y«`9ÎJS=yûÊCOa:´ý#ÕÿÁ*å—éŸÊèšy›äî5k­ü*™7]Á¡y“{Õ¬“ùF·¿àh ¾?š˜)'¼ˆm¬XÙ¡bí-õEÅ#>|±WæMἜ5Cäýëo{(x šÚ«gÖûÊ»NÀZJšäœTŠFîöÂqÛÆY›/|I–Lä„pr6ŸBvGØ,øœÖrvŒ- å+«:¼ú“IØ Àв3Lö»w¾w²óëÊÎÊôþ«k§(ÙÉ’XË—ÙÒùl‰%b›)K(–[¸\  ;…¾çþÊ~š˜Oœ®uõ[s ׺¯öNßkNújíêx©$`*è¹û±¨ÙËî­üaWY±d}Êv—‹¶tº„G¶ï-7y›Õ¬Ó·Ódfz ¡ÔôÏÉåŸ#Á®Ö±íåŠ%]væ,”W 8¬é nÿWYZ,[ñÝg~î;:ú’‘a ö^Jvi’·,('·†ÉË­?¹|áÑeº‹]+ëнY~wòµkà%¦F°>Œ¹#£¿™²„X™þè mšÂ‹ë`›éÀ&ÇzÍÚ,öP² 34Z2V‹WYåEÐï`Lf¡é¥—µ‹f39$ª©°ò¸Bú°’öw`ûh’H `H IÀF1€íHL—.×®$€*g÷φŠ÷ò´ûò¶*m§&ÖB“°sçÎWÜöAÛ$·ÖOL5Nï:k‚ïåËG—ÁõþîpLd˜€£#*€$:}¸K2á€èºŠåmÿógµ€©øþÇn¥±Qv8yôÞ¬2åõEq ÒK6àüÁùÕ“«µk‘@†I…¨û6þ¶»|tI’ 6^ XF/?Ûò&?Mb²B&™ž f_„”L}Q±*ù§ãìkþ4Si*¯‰¿ûàÍ`5•iþõ÷ÊŠÛ‚ÏB°œX…å „g½˜>§¶ÿÃV—ÑéÛ|#úB0zJpöõ‹Ë8Š‹ÒŸ²Í™1J¾&±rœËåÏB5m`¶)¨¼sÍEH>‰Êgª« ö­Í]rB(6‰wVásmÊE¿øcU-ΚÄö] SpˆÜ™G“Ï26ŽôRÐøbvþËÚ±ìpš‡ÊÊÐJvÀ´ú›vÉoe}/l!µ|µ³ê $™Œé×NVJµæÇ•€÷,°Ù¾•ŸScÙA½œ`ózêYÞÒKY’½‡HÇÄAìGè÷‰ÌªST²ï£P+Þ¿@Ra“œŸ+ÎݽàX±ž7eÕvz|jø-zMj˜u% èëYù,£G$™~J¹q?ÙÐï¿ès‚3áèrßÇšÞœ†¬€É¼ÍüØ"pøö;Y.V8Vó¢r?* žNCšz&£F峌í#½”dw`r^ðM>Cj iÛö7SK"°?yMr¯c]y’_º± ©IQÉõêë©Wj$}áþ£E‹‹Uu( ; ¦ÞÓ”©}.÷ƒAÞ±¼í¨›0­ž±Xò›^y¬à5INd«¼’Á,A`7Μo¿8;`R~I;ƒ÷¯}šóª¼×/w)¿«“²’ÇyFÔÛþ/~ìC/÷c\éÌ^”›vÊíŽc÷FjRÔ`+S'¡‚HÂ9tlF§²œ\¬p¡wWÍ3“ù†öc‹`À›áÈÉ‹‹ŽÕ¼¨\N¤UV¸½cðö·šÂõÏÐÈk’+èÅëÊS0%dâ’;êÿÔ׳r¹fKÍz2á¶YÍŽe£Ý÷Jݬ$-ò@®¤UhkxF€zvü¡ìG¸|ŒRPI²¹&~Êl Ï0‡äh·C<”\wȼ·£¦þk_H`ë ;}¦«r=æÆ3,ÏS7Ø@¦\7ØåÀŠ˜K2ĦKj2¶~«ðH9ÛwÃ#»GÀ²î, Z 7!3#Í0À¢Kêç€P¦¶ @p¨ÛØJgM° TÃjð­–a*~“û;.p—‡“Ë|Cªä^¨†W@%yzìࣱ]4ù¡‚XGß½ €&9•?VøD6¢lˆÝ²B’E厜{h޼€I_DÈÁ$Ó3ÊIb‡.(*V¥ä*þà(Êk,V˜X7Y¥Ø`-Ê“FyÉ}NؽŒ>LÂø"Áok¡šXÍÀ$þBMQúS¶9ƒ£È×$VNìriªœ{NSùD’P†_À>´éô-d€‚¹óÈä¥å¢äxEô²š ¹ôä± *S6‰oîs ˆ1c}Èîôz¾aÉž¬™5å}kŠÊLŒåÈrzïtí*’0éó¹)~µœ·¾!LèU3"Ë¡žSààΜ¯]`[ ï’ó»Ï7Ðm°»ReQƒõõ_g/Ö®‚Ê\#}Ó5xxNC1 l\0¥ÔEÎfè*Y0Ñj“¥‹ËÂs €cÆ&9€}`ò];$LFÛ¸ ‡*ìètøk;ã’íãÁi5ÃŽ04ÉÖ“}Aƒ €½©™A²-¿Ì”‚uM¯ÀÕß="Ã`Wüy©ÍØfþ`úöˆ¸Î6Á……*ë[0»Ø§c¯ôÛF.3kÌ^s:æ_Í¥Ài^ŠÉ·ÃIëfåz7nµ “\qî‹à‚#ºi î˜ËŽ~/#\éWH§µúè3ãâúcVädG„èŽüRTî®y÷kÿ¦ÞCZË[~’ïäwIY•ì°&8 ’¦XÍœ _4R>ÂKÑ™LÌ.Êÿ¥±×WB^À”Lü%Ó¿¹y¼Ø¡…´yðˆújÀ„Ãæ…C(†vÖל˜«÷Ä’‘Ñ$''~5?’‚í£Yy£ÜÒîe÷aZýÄèˆþGyî/ÉV5œééLÕ“1ô?°“MÉíòe¤9è¬OhÖEÞ™ì€)ëµØ]ž¦ÓjØ,! ¡Ü2ÖÀ—[NA}jê<®2¸ŒåÀ‚ŸÞõ?òËJX=¹Ð¼z3Máڑ»äüå¬k—õT);$iTYmhBÿÉ£ïÜ#B*ïù*þ˜-Û½ ·†p8ó5a¶7¹m­àì6þåR“…ò/òAdôa¢ËàÍhþ¥´³åbõ‘¬¼{2®©6dQ~¿š®$ý–þŽMÊ™•\+M…“_þ!”Å?ª9µæ×*÷Œr_‡Í-Mò2L­¹±É%oïž,Sy¦d·ï¯þw_ÍW²¼±¾V•¿u5W,XHÁ/ge @¨s“ ®Ù«2­¬^ñއ2×\rë&îŠû¦<ßÓùƒóµ«`ëj3L›mÒ*»}wõjXØÙý³²±¼Ê\&€Ý `H `H `HX-`ª‡­ÕÿMŠÊ-$9D›=u%c°3ŽÃ„ †³o€eäLþ̈ÎDoÎJ{¯àC±bc+ÍŸÎ8­Î²²¶~b'|4V=Í5Œ•é×°f¾žÜge4É™oVš${ÜtM ξ~±±cùµ§Ó”¬¤2hðO³I‹^lIg¡ù!€R›&¹ØL:òT;e…7Ù+ZÍT“åË”‘|v€C¹|t)opvÿ¬¬äد ¿µ·ù™ ©U²)£ì 3]Ÿ ¡'·Øm¾Zæ“0­ž¥È礦„¶õÐóçeã€ûmß5ÍëÈÒ$1ߤœùj¸ïúlSvÀ¤¼¬Î„ÒËŸ˜ÿk#YÕã¼bVv€­yÿ:ðF(ž‘×sÙËÊΠÊ-cÛ ‘æøà[¾¦wi¬f}7Sýé8ÛÄ>ÿå«íŸxòˆÁB”ýS…g\yšúg6¸A,'—õ¼gU¦w…à 8w¼ç¦Êîß/¹Œ«b]ŠÏºXÁå­yvÌGßTÓ3¸ÓR(Ç)¤¸wiìL‹»™æžN¬ÓgY×[ý”LjÉÚ^ó:)~fõ§¯Þs+³“¹ ÁOò/*§3§XáXµU晆W_CÁú/™•j’[ŽæÙ0‡éSH3¬ZÖ»rúf2ßOMT õÕJW£Õq[U>VaŠ÷à7àðj 2ßå­<}¹bNØ´3yMrÂ%^Á?“_Þ±x«~Y_7} ®a°¨š ”—®¾|zÊvLpËX_n9«+¾x튿”ûšµýŠÏlA™õiŽí›qàÊí¼¦áãÙV¤ÿ:ɽ5¬þˆÛ¼§Ü‹`§ÒuŸÙšü“É–mó%Wc®€iÇ1¦p¾eפmùG{v€…)o%Ñ¿+ïBW–“Û»t(ÊuÕ_‡úm0wÄõÌ–UO?Ý£?kØ ¾ÔLiëIžÎÜçÛªmn™Ú°ÓƒõËÛ_¯/AÞÆŽÒœˆM.ç©76[ìèòʬoJýu¼4yÊòYÔ?•ú½”Û›û gzfý žŠ£$jžwáy)¾ÔÇ\rP>‚€@ÓƒÓ_£¹u&w_ýO¾‚Þ¥ÁÝËj%<šU`ñQ4GW^Rýéäֳ왕¯RòÔ4ï2H²+»qþà|í*Ø:2LíìþYÙXÞÀ>ЫU‰€ €fº‹<º«ðZVk’Ó ãÖvÇ™ŠÚB}ÖøèÃ×$—5W¢0Wl/g¥ù³ÉÌŽ~žŠÓ% ÷aÖ_ÍD†òTŽþ¸¹ÏÊÈ0•Íb,¡xŠGÿ ö„kš‚•T þiÊS`f]çVOýD†É{D•1mšä„Œ‹’Ñ^ÿ÷²Í[l‹“,*w²ž†à˜²ï’[=K‘5ô{e ¹õi~qü³FMdLY£Â¯øÕž5s¡fÖ§U.Žÿ¨Ðc)«žûžS€¶ Çaò;g}ï–Mñ8_r+3»:iòI•Ç/9Öw;ØËÛOAírÖh •Ó{§òÃZÆ&¦Þ‰± –ùa“u”æ ^‘P熥%ï…ÂeL¹Óøù!NåY‚3j¶&’šÃê/ÎàÅmÅ3SÕTGŒ`»xxqvÿ¬¾œš|ðÚ×7æ kxŠ{‘—a’»QkÖ×Lñ˜;aî!äù#“eÖ_œd f¦Ì­`Œ±Âq&Y ¦‘.]¶*?ÖIÀ¿ñVDK%6ú‰~€aL“A$sö’c¥|Pù* ÷Û—(kô™äÓ­ymhŠÅÜf¸’†`õ‹³z°®1>ÿ£¥µë¸OÁC’ƒƒ˜}…±TìmÌJÍ+š1M’]#ä‘PôÃÇT®TV)v•’· åŽ>“õtT˜!c–4×\r4Ê V¿8«W88;Üi+wЖ‚ò“_Ïú$wìR诰eYÖ¿2ø(8hq±ó½ŠT0¤­§ÉL•¥õX޲ÑÔæ«IÌ2ƒ¤ø—B¸>~§Òä•Ükêe;¯¢Ca.9XZ°'ʦL©‹V § )y)b+ý* WR8è>lÿU´3L°œdV ò˯íîþýÅšò“w% —Bs}L?žæù•Ü«—;DN,ª+¨'¹¥å0À,¦o5çk2Ö˜bwå®9¨s;•²í&Ø‘9K²‡µ² ¶~–úqRä¢*WêOJ_%áª)ÂQ†Ì×ÏòOÙöµ¸r‡ªw:ðe oï8”6+$Ó××°rf‚²™8Ñ’½à¤rŸ2ý=4šKÔä¹ó9Ñ’½à¤²Î=xþÍ7Îý=Áh^ý5q¦ ÐÌ!‘{²¾VOY˜l×ò£”µ­‰r¯¶›ùÑ’ó§&fš"gŒ’†ÓÔß ãGKΟš˜É>wÍ`~Îéh6n²YÁ^Å—z¾§¬3vú€¤äL¿7(¤¸êÑÀùƒóqáë?zÇtŒ™>ùá{Ó²Ü8Õüë0Ø™ºùW¯‰ƒ-ã)Ë8§Ÿ/x:BãÔ=ó4UUZæ)ë&k’'Xk4ü…5hee”ÇÒœBårÒM½›í<“&ZÒ|;jÖË5mòù3FSdç™4Ñ’ò¹SVX¸‰,øæÉÿzÝj¶_þ)Û¾Œ “|÷¬æ^Ó`¼¢¿›7xЬÛtýBœ:$¯€Pá:hnѼj¥ù}¹Ê' @ïb·‰µµÙO'<:ìä0h¥M“\YÑèwWú½ØôYÊ‚ fºÕ³¬- áÁ6Έ¨­h˜ ‰h õ²‡XýÇ„þ«jÛ÷¶¾Çhý±¸É@®&¡Ò*÷É7A¨„V²&}cÝá­‚ýäªÎWO}edBרšú¯þd°q…Mrέ·)k¾ä–ÐñHX³ØM••÷åV>Y #`zÌ(ï5ÕßHY§nì6Ýäöò r}„Ûè²*ãW©áMžúƒÀ$¯I.÷ŽÜ!ÞÝ[9ŒGlM“Ûq“u˽Q¶¬2eµÚQ³€ƒ›qàJš~:“€`®€‰ÄáÉvìôÞé4‚å1üôÑPö]rŽƒ4îÌ1ŠÒv΢‹Ê(`b…qA?)г&Ù}3ù£«øWYåϹ‚Óouè…‹Åj&À69™•¬ ÁÚ7Ùd¿Í¯ÿšÓ|L°C&\˜¢„éÏ&AÃfÆ\øôå ñÁöä)%rçQźfìô X….Ø •z653æ2§¯¯plãúyT±L°+~¸àü© ¦–¸à˜mÛ™s¾Ówê& +8¼&§1­<.V´Z“ÜZ}›U_H«3jÞ—0˜$_½V—.§…àjcÐ o`${pWšifÌV§_sʤ…öŠ 쇉Ld`+ lN›Q±©»»ÇÒZ§ìá;e¹3¿÷'/äéë7(zÃUv|›g·;ËÊÚúuˆHðQ§>Áe•†/Zý…ÝåN…±rä³PvNœ£Ïfî+€Ò L‘Áø¯ÔGKõ‚3rúŸÁO åGAG§¯Ù˜ÀíÈÈ0 Ñ”S¤Õw|óœp-YÛXÅ’W@¨¿^S¥`¯Æ‚N…úÞ‘ÊJc©æ}6³&× ä'ZZ… ›š³ùé'ç6uNÙÞ@¸>KΣŠù´éÃ̸ø©gƒ²Â›ìë¯W_“ä'ˆý‘QSNýÅIÎFœĘ'=«b¹¯Jv¢Å^™Ü±x–Ìâ‡ô;níôõçüõ˜<6%»“f³Yé_Lö]e%äÖÇÏ!;yç×Cý9VVXS™Çâ{€ÌÁ‰VlŠâô±Ù“ßS/¶Ù°j¬¾çÝ|MBÁkìÏ´"åªÙ±IŸÍÕ_9Àž˜(á˜áÂÁOmÞ%çdr¿ s;¾ÙmgsÆL±®N¹ga×_3SÖCÂ=e•Ô1vvƒØ±É¹YÕPlŒŽ.üôÑPFÀ$tF ö8FúZ ã[nÏD¹wžpšúk;)ùˆÊ+æl¬é))W2vmÛ>›ÊWëÊëôüöM®¯éø¦éu¨ì™¨¬[Y²NJDMH¡ïl¨©ä}6•u›[2ãÀ•´¶  ¯ÀÖÌ0Ñiexå6¨v¦ƒ´§ììt¶à ¯À>0—@@@@ÂjSýf 'AË-JÞÞ~tõ©÷@½Ú»äŽI3¶5ؼ€ÉN–8“¤ÚÃç8CéÅŠ­4Ú)æ¡Çà!4×Á>ëà9ÆŽUpÍõW4—Ñ$'Ì®ªœ¯Í$bÅÆŽeü Ô”…øó~Ô7™ÅN_˜“¤Õ!@vùèrüoíZ¬æôÞéøßڵ؉ƒ_Ì6}˜bµ‘äGVa"ž2NØ4‡R;¹WØ>}_Àâb—ïD8Ñü—u:sÔÖ„J¹1SìD–Thóí®ÿš/èäšUÏ~;¶6¹˜ w™cKYvÀ´ú“-DNÝìÜ’\g¢ `7fýu$³žm!%ìIú˜ik'RÆù^/N¬øŠÚŽV³kÙ¾•¯›©ÝmáäGð@¦°¦#Ñ­r…9;êùÚNb½uOÇØ¡s;VjNÐÔDÓQ¨€òÐ&Bb×ÜÙ]îîÙä4cÌ7úÕ“+óçøïôgÿŒüótj;ý¬®¿˜Y/ÿŠÕô„nxÍ ›äülsîîÇŠíKŸ&ã‰%³e•iÉÞY‚ß7ÎJ¹'¥S ¦§£þ(ÂîÎíOžiMnwFͱdN´d/Ô÷gr:•êë™uk>ôœ/x{¡&5¢é;ßI­¥áÅÔ¿…†ÌžÐ ¯yFÀäØ ?JüüÍœb…cKË*$X™´:–ò ýÞæú„í…GËö’·~÷ATVÆ–œ?³Úæ‚ݘÊZ©r¯dnùÿ Þù³²9©¦_lwÚm/fÛ7Zó-“òšää³Õ¬þÒR~PÊk²>m+ï_“Ï¢¦‡{Öé×”ôKÈîìXè`eê{”Õvü;p>.|ýGïøŽ1Ó'?|oZÖ´§È÷ÿ6Ñ6ébbÁ`ËãxÊòÊ«‘ s{Ì$ùf½˜Í-pÍgé{¯˜-ã ã˜Lgä²áÓj¾ïåCÛ™Íð¶ò÷nÙiš0ÈF¶¬hie§c¾¹ƒY´&_ðš!iÚžÔZ¸˜ -pÍçé»Çnúø£ì¼Ú–ßãÊz ÿºÐôCÏ-°,ÎÓw †¦†’1<²óLÊhÉÜPRùñâ_s¡LÿÔŠŸ²ñû{ú.wz¸×ÁÛ1w°z~‡ÚV'µ–ù.¦Cxmk.µPNÃk^0í©hî:·j›[¦¶ÀÙ7‡ŠwóÝo7¦È}Œü£hík·Ô;QˆÐ5÷4}~Ì”ÛçT Ö *\(/§/fîîzþ×|î¼þ|‡øË¬íI­¥þbÆÈ¯óàE“WÚåÌqÍ™KÀ:ô}5w“hþÔ—SÜ=·£§¾zÊ vÌd¯Tʾ•B'QMÏÊ>¦ûkÞ^™{âÊGõÏ]¿uë/fåÛ0ë#B޲ƌ}˜1 dbw6„󾑮6âbL°¼Åú úcçŠù^?æ|[\Lšä`iK¶Ël!TZ±ê°ßîs8øÅ\-ÃT<ʶ¼£ý¨?ä7@=g˜zì[6(/`RN])L-™;mž³Òü)Ìï8Df¸ ž‹¾æà°2šäôSW&KÐO›ç+—_p¡²æàÈÚôa ­!L-ÙpBÍ…k(»Óê™" ž~¾zÀP0)ã{¨ò¾Bœ~k(]<¼X» Й»äüÎÑÓIæ«`¾æ5zwõäêàƒ©@Œ€I˜'/xKZlæÅ¬ióüc E ëå“JÖØi~1@–¼ Sî¼’C¼»wÁ4“š¢‚ë³fîÔœ,Ð/3'kÒÅËóçk×6aÆ+ûMÒô[s@O˜1cêNËsMÒo§é~k(M¡ms W›aê·=«ßš³"½¾Õ&ß°"’LÇ1>ËG~¢~úm¿¦Ž<„Ûž'ßkûé%ÿÞÛäÆõÛTVużµ‰Æ¡×Z°ÚFMý×íäP|úB…7Òm#9Iks&T”¹¯¥åO* &à zL2Ù³Ln|HgBÌU8OnÖsÝê"¯xjN¿/ \d'±”•gêâ «A† ÀKO/‡Lsµ×Û“vû_'Á߯~!Y+ýrì1áü§¶þuÁƒ*¿M|`GÆúDKìúûW8y^Ámü“j›Q¨?ý`Å žY奋m9(^Ûs_d½}³ã÷Oî9y&áò 'å?ÅÇj… p\=&™‚œtŽó +DKö§v°ýJ[ðÐö÷Ap÷é{ÂŽŸŠ”;ႽPöt §œÝòBmc—×I ¬;yy«ÓÏ"ŸiîeÙB*e2~2LcýýGïøŽ1Ó'?|oZ–:í`ºëù[É0x©—ôRŒI„,ó‰ìb²:ó$ƒàâpAŸN[÷²Ìtúõô—eá—±À„A&0²)£¥=!`Ž®—Ï;eW†`;]l¯¬/uSòZIed,h˜;\¨¹, £«ÅN_Ygá²%Ä^Æú×vq…m±˜iîhiS?B &7ºH/Ù­vn?Öêaw –ãw(q ѯ,;‹‚Ý5ü ¡2\°ë,wuÏ:¯Ø´µÓWÖ9÷Õâܶ–µ»þÒU^d?fÊ–ü>Lõ'µ m¦ÜG`ˆ¼—§ž ]†>C~G×àŽú~Êú–©àÆòÍrÒLQ‚hÑ„ š+©¿ÚÉë<ÓWcýé •^u¹¯–XÉšÝýjÌt‘§žŽÃ«y&M´¤?qá¤êëߊ*ÃÔч)ïåCq⃠&ëïsìúô—Ñä"Çn9<”t†i|‘óÒ;Ã{ù€L¢e›áÂÔ&5ß2?ýe´ºÈ&Ït؆€=Ûx¬0wkË6Oá6¦V‡;l¨4Y?`ên —ùÈî±/àÁ?"`Â]rÀ¼ºî6tñðbí*À&¬Ÿašl3k T ¦”zÉÙýƒ @ÂV2Lö„ì€íËjÝʘ„!\ƒ­8 #ЋؠÉ]£À–Þ;Íê ‘0™õÍŽ\ôk7szOz¼%b²3Lþ,BúÄÙ& ‹yË8 ûͨY¶÷Š­l…A2ìLF§o§ÕÀÌÚ=xŸãÁ•ÊØ™Ýáö›ýTØÝÙ«¬(8¬fwÉi¦ 4ŸÎ|þœÞ†ðÞ F<~!N„ÈRØé@s±>L•!މ¨bQ I0?jù´zašÈ†bpÍšä‚Á“ßL@Œ4grHS‹›óó&ÖÌgðÆ€¤Ú€Éþ¤–W }˜&Bãš ¸WYQpXÚ&9ÿóÔÏêû1Sl%›Ü¡;wKå^³¾c¿—”¿£ ~n“dvšrj05 € 0&ß°ÄR*‘a°&Ó”&4áÉÛ("Ì€YS2€ƒØJÀÄ´S8ŽËG—kWa+ì8FÓí©m¤ùJ°?›˜Îœ¯]`!/Ö®ÂB’Cøw×£Í6±# 1òè0Y?`b’NÇøR_ðk×b!rØbG€&mæ³î€™ × @/0ÑX`>ëæ„ÈHЋL´”Xغ½ˆèÃ@À8LÖa0(îüšÆ4Ê£ÀdýNßK3ÆR“q˜.Àþ0h¯rvLöÔKƒuË´>ë~–‚]4UjR&€ã˜º§ß$€2“âŒngºÊmÖ ÀÆ™N“ã‚2fŠýnÔì¢ÿh²?o[ý¼P£Á]ræ³ÀD*öŠó†w>kf nœÃ9ÇõcÉ…àŽú•|ÒäÜb¢™ë“-ù!Ƈ°}˜ìˆéÏi3«¥ó¨Fø?³fý±#9¿J±N¿cr%€Í2ÑÒû×OÇÿœ•JÎû}úx4’ƒ÷aÛ&¸+À*ò:}ÛAìÝk¶)x´˜ýd—¯9\l²tå¯F{3åLç  †-9 Å#›5éOÆ,óó@RÉ]rÁF(›óûÉß±¹éȉNŠçìèœK0jÔ„’¶À–œ?ç Ž_P@¿ ;}[²üÍö:ÄRP¦1Îþ 诰§÷N§9^¾þ£wüGǘ链7-— Û›üÐÛǧ"p@Ça*ø,XýãCY“: ¶ýW$œ€1a Œl•ÑÒÉvÁ¦|](ìôkžwZ¦„<“½ËÜ'éwWWV@Þ1¹ÀÅb¦‚h)ö~/û¥Dv ز¼a’±…¼¬/­²JþÊâÍ”;f­°®1$:½w:ÜISÛ\n´¼ç×é×èïeoc–a/>O€i&á—M§ïaRAÀ‘Ù1“½2¹cî@geð÷¤°<(€eh¦ý½]5?옉™ÌŸk×Àv5é»_IÀÁ™˜‰h €,0Í7 &?û7ï®]àЕhHwÉ]<¼X»zë‹f˜Æ_]úy(FÞ ,©Ë>LÓ@½€üøì‘ÉeØ·,ô¢ëðΦñ…Òõå Øùƒó~¿/^l¶åJ£³€ ÐV×ßa‡L)õ?í Ùx.9€ý!`phã¯öû‚XMrŽË„JãB†0nÙLÂ^±YªÌþÃGG­¹l啌é=¢|§Ø›-üæ’ßþ}q¢%{!ÙŸÉ|g˜¯çÅÿR‰=+Á>P¹&88ûdÈè_Éû£Í0Ýü¬¼s=|ôËá¿_ß®8Y»æÀ8¿Û²2ç‹ýŒÛÙÛß–ÌŸÊ<“3Õ×*«ó…´×Ÿò¨'¤|„°fJ;9Dþë|Úàh/¿tÀú¬¼~ú'?ˆno]èào¬‰œÇË]étx_þ¦¦Ÿ•7Û¾ÿ»N&ä퟿Áäž³R~”‡;fýª­ÆnMÞ•oÿ탡)0ÿµ#}n)Inªºi?ç« àsZå‚)êé$øµ»ã—\8`zúOÞ½9íÿýîðߺùû­oßü;}VÞ¹¾]ˆ²/¢Aƒã—8ɽXÆ/+-¤9p4š7BÍÛ¿~Ì”Ûç·l:ëý^#þ£±]‚ýHôäšà ’ïe¯“¬WòÎHv7ió¹9~\ÞþÜLFW ®ô»8+cÝ5äÊkæPóöï‚3Ù+5ûÊ-¶&ö¡ÔêÉcá Ê^Ÿ±õʽŽð’K+p“yû~6üåGÃG?>ú«ÛäüÉÝ?ý¼Ë ^>ŠÆ:Žåæb!”| `]~WîÁ{/Äö-뇗ûF(xûwÄ ˜ƒ€@;“õ¹ùWÃÿyA?}ë[r¥Yvr¬N~eú÷¸é_ó‡öª|ûo– ’ˆ–Èònz‘[Ä‚I¼²Œtr¥Üü° Cô(yCCl>mÞ¤±f¯w˜*Ð(¹K8vßMÁ^•H¡_F¼Ýö'9¸9¶,8@æÐlX•U>FÒ3»$¿\; §ÐóçkWå.^¬]…é~:‚$ì/l,àìþYÍdÃX×øÜÑ ¼$7`"¹3øPÙîpÚ»äìFe+ 8(Ü$ÇÏG`¯ü¾Á÷»3mˆ°{¹jÛ—ít߇ @sMn›âw€-?è²úð0‹%™”¸YÀž0xE«ô·_Ø:}¨¼v†€ À—¦ôÉ!p0#É€—H/@ €(’L0!`pƒôV€äìþÙå£Ëš1™î~í®Yö'¶-Û rû` Å“×ì `˘̕^šb;€pâ ?¼ÈÝÀ?bnÛ×cý¡I@BYO¦ékÞù¦ÿ4 `µAðˆúí@ ptSzéâáÅ2‡[1Y2EN&~R殄íc'¥yHh|tRbC(W`ad˜h£%}’IÓŠËý˜“8ý«Ø…Š]4çQÍs´B† @7œhÉ^˜£?““Ir¾Å•ú4†SBî˪-ÔÓ‰6ô»Ëk˜^ ÆCYÏI&Ô#`Ð?Zrþ\¥ø sr“_0Ž©)y™LÌ”·³ÿ"qŒR䊰4ÉèÀé½ÓóçãÂ×ôŽÿè3}òÃ÷¦å«'Wm­ìÒÔ„ ZuÇ..9xR5gºXÐC 3!`Ð1 c¦qa Œü˜i¾hiȹ«ÕWµéëd:Z Õv½Ž„äVÿâÌB‘ŽÂLh’Ð ™ðÈù³I´‹BL€RPš~ƒd”[S`YÖ*xÖ±•rQS; ýŸY?|Àù]Ú‹/uÙó˜tÙFK~H¡iƲ·±¿û1‹Û vD{!¤¢o’ËÚ=y¦ssâ-å9h’лmÎ^YSf2zW»' òAs›Ø’ËÂÊÊÝ“ëí8R Z¾¶ÊšŒ]‰È0èŒÍÑoiûhoFÀ ?&H:r´´ý|ÉFF?êåraãh’Ð¥c†J“޾û·PÕ-Ô;@† € € € € € € @—NïNC~À‡ @L¨4.TÈdjè/Oœ|b»Ì$xˆ²™tVU¾nÂQZNe™ò.û6¿ÂØ&qKõ1S.¾»¸55ÜþÙayLzb¢¥)Hšþ\ f &QLÊL1+ä¥ìrì ”Y!•Øp*×$ëX¹/BÁ!”Ç.lnµ ª!ï[ðb@_èàN´d/÷g¾Éìà#8-šÙÀùfÍ¡&l;Drƒ`™rMÚ¶9¡òtbËVy‰‚ÏH²Lå¾¹/t‡€ @ühÉù³¦xð+ÖX =Äb¦ä–üÖ«¶ß‘Å¥ù5ñ;) /ˆ#õ•Ln)t*ª¹e;æî;U’ÜÒÎ0è†3­-9QÅ ¶ÂÔ4ÓÄB»L»2Êš4¿­NÇ^_Ù¼UP½²}³^ è}˜ôd Œ¦ ÉÎ3ÕGKþ׳°üŽ>$H¹{𸹕ª¼,Y7¡´V§£¿°»Ë»ì›[gt‡ €Î8áÑê½¼{W–zéHe+Ý0!`Ð$-ÕÛw´4T·„ï‹¡I@—• Ç4)¨G† € € € € € € @—NïŽÿ­] GÁ8LúcB¥qáêÉUeiþPÎöTkYÃð,<¼aÙá‚{éWÇD† @gœÄR«<Ó4ajÛYiì&=1áÑ”Xšþl’g’Ù!”ɸW:»ÄÖÛ{™-…ŒNl¯Áš ® ’± ©&Y_8Ð/2LºáDKö¬ý™Lˆ`G Á•þ.š¢ÌC±üVp/S¸³R_Éà™êsl¹…]#à~´dþl’g’%ÉÜI“®?Éí§hfÖDY" †€ @.]N Á9wÇ8IÞ@ÃnÃ2‰cÝô‰Iá$C±`=g­<‰%Mr:` Ùê£%™Óö”4SU°[’¿Ý{]XÙ°Vól€>Äb¦¹£% “û1ÚÆLÉܒ߃*ØJÓ‡©lMá@טtÙFKÓW~0.±[ÄÌr²™,3é×4{Ù• n“{¸ØzÎYל Ð)ú0èÉMA’gªŒ–bßô~pà,Ç‚$¹dy/Me²öMVR8©äY$á8È0茭Øà8˜ôÇIDK–A“€.*X&€&€&€&€&€&€&]:½w:þ·v-ã0è •Æ…«'WMÊ Nú¶"ýmÁ- æw[kJ¸dý™«[@À 3Nb©IÌä|%Ûóìb\|l €ž˜hi ’¦?+c&?aGNӟ΂½™l9ËÔ¬tj{T8‘Ê#jŠò/‘P”œ7 >jŽhBXåÕÚ¢€n8Ñ’½0k&û;{¸ý’ö¿¹c{9ëWÊå§ß]yDÍÉGϺÈÁL5œ@ªòp@.2LúàGKæÏ&y¦I,{!d2¦,Èô}Ìš˜owÇdáz±B’…×w~Ò_á(䊰qL:pùèrZι;ÆIòzr’cÈIi˜¢4!H²ØšTÊþÒ0û;#lMr:` ÙZEKIN{!ÜÌì3¤,Ö)ÇüפΆÍG$ÅW(FÀ ±˜©>Zš)DHæ–Ìeª¬ç|Ä8…8ÅÃø}­6ØaO˜tÙš·ÄÉ Ø›9Q…¿K°I.¹2v#X2üŠ"Á“e M“ÊFƆœxk•:ôaГ10š‚$;ÏÔ¤%.gÄ"‰à.C¼=.ke²ØØ£±B‚Ë­*¯ï¯9P¬ztÇêÈ0èŒÍÝoI‰¶!`ߘôÇI›Š–È|;F“€.m$Tš*»G† € € € € € € @—NïŽÿ­] GÁ8LúcB¥qáêÉUeiþ ÝöLjYc,1‚%°Wd˜tÆI,µÊ3M»'2Lzb£)±4ýÙ$Ï$³C(“@ ®tv‰­·÷2[ *›ØB²’šÃpaÐ 'Z²fíÏd ;à®ôwÑeŠå·‚!‘ýPA%…Ãð‘aÐ?Z26É3 é¢dÆÙ ,s£Ù>3•Å=$–€,L:pùèrZι;ÆIòv–ɾ›MÃhê¹ÙÊ¡I@Ld#[}´$s¶’Vlê2]×íªWÈBÀ ±˜iîhIcJJÙkfŠ™”úõ‰­ DÀ ~ÌÔ0Zšâ‰`÷#ýØ¥í•C¨KP0fJîäTÞÆ.¹ìp|ôaГ10š‚$;ÏT-ŧUË_ŽIrÉò^šÊè×€ƒ €Î8áÑŠ-q‹¡5 X€þ˜ éÑÒ@˰4ÉèÒAB%ƒ X&€&€&€&€&€&€&]:½w:þ·v-ã0è •Æ…«'WMÊÆ„\k¸HÍq êV:É»b+ŽäiíÔ!8{`Ù5<;†<­GÀ 3Nb©IÌd¾ää n¡q´ïfûLÛž{Ãk8v¼¼k0艉–¦ iú³IÌdÿ¦r +ý’ƒ5™¾ä‚‡vŠÊ=tÙéd—š4Œò‚$÷ŠUÕ?ºsUím”$$ OYÙµ•K(¾¶(C&Ýp¢%{¡¦?“$Åb&L˜o©²•þ ÌWò;/÷Ðŧ#W,ÉÕ_y/ùL…'ÔlŸõTËŒ]™úk[ù<Úe2‹s12LúàGKæÏ†y&ó&÷à1ßXzò^v“Jn»O°ä%s5ÇjRÏæ'‹™ô5™µÙ®ì€\>ºœ‚sîŽq’¼FÁ÷Ÿ¿‹ùk¸ öª¬RnÉÁJöž“ØlÜ0Ç…møZ‚ƒ&90a Œl5Ñ’Ý„!4É;:Åz“؇ðÅn³r6¿ƒGI–œÜ]®9 ¯ŸzúgzLú‹™êsKJÊ(Jh̹{åVÕôh)w@¨dMÅ »ºâ*éO§ìä–æCÀ ~Ì´X´4x·#ÙmvÇáÁûÒJ¶’Ä6pŠÄoÁ²C—íîW,÷J\y¯æMQr²ÊOžŽŸ;tQù<¢ ú0èÉMA’gª‰–„5ÐoZŽi’ß[Évºäqõ‡®Ü=¹Þ²Ž•uâš2“EÍ >ãÅ×6ùZª|‡ãÕ&q£rKÛ±ÁÆ)à ˜ôÇIŒ–¶Ÿ!`¼Ÿ êåųe4ÉèÒ¡B¥IGßvUõ xFê‘aH `H `H `H `H `H `Ð¥Ó{§ãk×ÀQ0€þ˜Pi\¸zrUYš?Ä¢?·WVQËy<®37ÙL‹%yÄd縹»ì;ëÕÆŠ˜tÆI,5‰™ëëÍž ­kËœÂö/TM ·vX €ž˜hi ’¦?[ÅL; e‡VþJg—Øz{¯d>CŸÅ >jŽhA¹æY‡Ž"_yù¸Éšë«]P Íe/»ÚØ2&7.]®]…4'Zšˆ™œ¯Ãé‹0¸2¸K²(óÐTlq~+V‚_[¡æÅb‘„|RYg­¬y¬L?¶Ëª§rße®6–G§oÃÅ˵«æGKΟ•}À§/³` 3} û:”ua¶NgëeŽobå¡ Njî:gm ¯FÙ¾æŠ-õ‹ ptcÀ±ý‰lM,XÕñä 4ä>L~^¡wýžQ_5·sKMr=#`Ž®‹›óÇ0h ‰Æý¨>Z’ÅúÐÄT¶¬-cËuÛ_ÍM;ÝÆ_Ð$¾ëϺ-w&rº[Í-i˜ü¡®”L~/™ÜªÆjîŸEñ¡õ'žÜ2¶A¬¶MÚj_¡Ý!`ðÒ9ÅþC¥ñ¿Õ[îü˜©a´$÷a^mª³b_‡Á˜i­'虩ÎÅQî"_s¿“VqÍ ªW¶ï2W £IÀË{͸9¿žÝ6g¯¬)3öëOm–“ýƒ%Ë{%»~'«^ò(Á[À²;º|²®s²÷}îîò.ûæÖ½ à a MVO/NM¶S±Þí¾{Me+^_ÍÑ€ö8Ûg‚$¢¥†ö- u-z´¬&9’­¥—Œ V ÛÇ4)(F† ÀK}%™`IL¢6›^€…0øI&¢€°Ý§—º˜o˜yw÷øiù1PÈ0xÅô1D0ìÛùƒóµ«Pn•YÈ0ˆÚqzéPç8‚)¥í[;Yëç&®^>7`1LÂ6žz™ærY»Ž"Ü$ÇÇpÁ÷ûÆû7˜:w1ÿÐ)6˜#ÞÈ0müƒ@C=¾ßxÀ¬Æ iúo…PÇáf˜ÎîŸñs 8ˆßï&<²‡Œ"Ï,ÉL¨ç,LìÐJ³lï[¹ôaÐ 'Z²È3 3‘‰²²PÁ½ÊŠZ€>øÑ’ó'10‡1j™þ¼”‰l|ÁˆÇ/ĉ¶Œq˜tÀŒ¼¼woŒ™ä ³ËÆÿÌŸ•!މ¨bQÔÖaÐǬ#Z:ëºd÷4߈D†)™â:ZÞýÚ^½(ïš•Ór[Á’ç;Ü2’ã™ _?øç¯Dèïþ§§få´Ü]ll¹²Ø¹U]êW ½{ûŸV¾;ûýÞo¯9޲AãS0=Mã¿öÓA´lÓÔÜ$¥œL’ÝL)WT•a&s1‘ÊôßàÅO¨'ÜnBé¿Á‹Ÿº`*¿:éRMÿ ¡€f–‹óÅ-Mü<Ñ07¡ÓDh\÷*+jª>LÁ4Råd.Nîǧü\Tl9Xl°Ìà!Z­ÿôk¨Ù]éýëÀ+擾WsýäNɉ¢²¬P¾óPðXþ‚sþ^ö±V¾Ô¯¦šìpÊÏEÅ–õGqÊ­÷w n³AvžÉ^¹v½€’;tçn©ÜkSA’m®>L&t°SMæQÖL:ÛÌ‘‹ ¢ÕJ»ÂúÝgeB;ÕdWÚ±…³MA.JˆKìhÆ/ß9–S1G¬Ú~KæÕLða§š¾¬Ï×îÚщ³Mó\”S ùS8®f›­qÂ#¢% ˜±Ó·û3%w"Y"yw;Fш…töJçÑ`UË4;högJî>„a÷àÆCªeÍ~T®XìQ}0Lœdû3%w"±Ž°ût¬àí½4mvö6Á°oƒLD´`³+`0vcÙ‡¼ÜÏï‡nÇaÁ•CfZHs e˜ŒIϬ"–éi^%?µ¶Ø9š&-“UšûpÉ•úpm¥Ê–¸j•,i®€É Aîñ;\0R †tÎÊX¥ýfb‡ N£ÕL¦£8­f±åe*3,&Úá…Ó ¨G ‡}[Àp—À¤²kòîmz& LÍXÊôŒ( 2™ž`ʧ  ¡ämŸ q¦¶­ås6JN¦ÍÖS`²;S[Ø*9žŽrK õ8÷00á¶wLæÊ0MñòÖ0gã9¢Šà!ÊVšeg!÷@³2ù{rã9šÉì8ÆïSUY¬B›û\Õ¸o”÷—9ׄ&Yw´iŽÛ°n½èqîa`ã6î¤×¦û÷¦¤´ÿÙ1­O.ñd¦Ò” ~óq?©Ï*q©kŒWo¼tüBеñsÌþ¨Ÿ¾¦8çî×î¦3L|Æ,ÓÊF“ALó¦7.u%. €Kd˜ «Žõjƨ@a‚€ i]I€elú.9€-x%ÃÄ ¾/3Ltîzm³ÓlÁݯݥ@Â?ú³¿þìÙãׇáùíß% 'o¼qò•±ÂÝY`… /ĶQ=X`iá‹¥²ñŸ¿ÿÕßþŸßøÊÝ¿ýüó›îL/†·ÿŽË/nÿU­¹óúõçOÇB®?ÿ¼dwÖ°†5^{tkõd kXÃ!D©Œsžüåÿ}gŒž_ýòúóëÀ´r/yåóëçËg׿þå·ÞþgÅ…°’•¬ÜôJa³­U••¬d%+¿XÙ$D1…ŒËïù0Œ¥<¿ùì»I;=qóϸõm2Ê[3nsçvÍ‹çvá·…|öò!{ãá‹rì57UñÖ _lìT#·b£sô–GåÀׄ£stŽÞÁÑ&qÎèµ·ÿðϯž]=¿þìõáäöÁkõÂõ0œ|¾Ýò sre
      Module sre
      [hide private]
      [frames] | no frames]

      Source Code for Module sre

        1  # 
        2  # Secret Labs' Regular Expression Engine 
        3  # 
        4  # re-compatible interface for the sre matching engine 
        5  # 
        6  # Copyright (c) 1998-2001 by Secret Labs AB.  All rights reserved. 
        7  # 
        8  # This version of the SRE library can be redistributed under CNRI's 
        9  # Python 1.6 license.  For any other use, please contact Secret Labs 
       10  # AB (info@pythonware.com). 
       11  # 
       12  # Portions of this engine have been developed in cooperation with 
       13  # CNRI.  Hewlett-Packard provided funding for 1.6 integration and 
       14  # other compatibility work. 
       15  # 
       16   
       17  r"""Support for regular expressions (RE). 
       18   
       19  This module provides regular expression matching operations similar to 
       20  those found in Perl.  It supports both 8-bit and Unicode strings; both 
       21  the pattern and the strings being processed can contain null bytes and 
       22  characters outside the US ASCII range. 
       23   
       24  Regular expressions can contain both special and ordinary characters. 
       25  Most ordinary characters, like "A", "a", or "0", are the simplest 
       26  regular expressions; they simply match themselves.  You can 
       27  concatenate ordinary characters, so last matches the string 'last'. 
       28   
       29  The special characters are: 
       30      "."      Matches any character except a newline. 
       31      "^"      Matches the start of the string. 
       32      "$"      Matches the end of the string. 
       33      "*"      Matches 0 or more (greedy) repetitions of the preceding RE. 
       34               Greedy means that it will match as many repetitions as possible. 
       35      "+"      Matches 1 or more (greedy) repetitions of the preceding RE. 
       36      "?"      Matches 0 or 1 (greedy) of the preceding RE. 
       37      *?,+?,?? Non-greedy versions of the previous three special characters. 
       38      {m,n}    Matches from m to n repetitions of the preceding RE. 
       39      {m,n}?   Non-greedy version of the above. 
       40      "\\"      Either escapes special characters or signals a special sequence. 
       41      []       Indicates a set of characters. 
       42               A "^" as the first character indicates a complementing set. 
       43      "|"      A|B, creates an RE that will match either A or B. 
       44      (...)    Matches the RE inside the parentheses. 
       45               The contents can be retrieved or matched later in the string. 
       46      (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below). 
       47      (?:...)  Non-grouping version of regular parentheses. 
       48      (?P<name>...) The substring matched by the group is accessible by name. 
       49      (?P=name)     Matches the text matched earlier by the group named name. 
       50      (?#...)  A comment; ignored. 
       51      (?=...)  Matches if ... matches next, but doesn't consume the string. 
       52      (?!...)  Matches if ... doesn't match next. 
       53   
       54  The special sequences consist of "\\" and a character from the list 
       55  below.  If the ordinary character is not on the list, then the 
       56  resulting RE will match the second character. 
       57      \number  Matches the contents of the group of the same number. 
       58      \A       Matches only at the start of the string. 
       59      \Z       Matches only at the end of the string. 
       60      \b       Matches the empty string, but only at the start or end of a word. 
       61      \B       Matches the empty string, but not at the start or end of a word. 
       62      \d       Matches any decimal digit; equivalent to the set [0-9]. 
       63      \D       Matches any non-digit character; equivalent to the set [^0-9]. 
       64      \s       Matches any whitespace character; equivalent to [ \t\n\r\f\v]. 
       65      \S       Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v]. 
       66      \w       Matches any alphanumeric character; equivalent to [a-zA-Z0-9_]. 
       67               With LOCALE, it will match the set [0-9_] plus characters defined 
       68               as letters for the current locale. 
       69      \W       Matches the complement of \w. 
       70      \\       Matches a literal backslash. 
       71   
       72  This module exports the following functions: 
       73      match    Match a regular expression pattern to the beginning of a string. 
       74      search   Search a string for the presence of a pattern. 
       75      sub      Substitute occurrences of a pattern found in a string. 
       76      subn     Same as sub, but also return the number of substitutions made. 
       77      split    Split a string by the occurrences of a pattern. 
       78      findall  Find all occurrences of a pattern in a string. 
       79      compile  Compile a pattern into a RegexObject. 
       80      purge    Clear the regular expression cache. 
       81      escape   Backslash all non-alphanumerics in a string. 
       82   
       83  Some of the functions in this module takes flags as optional parameters: 
       84      I  IGNORECASE  Perform case-insensitive matching. 
       85      L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale. 
       86      M  MULTILINE   "^" matches the beginning of lines as well as the string. 
       87                     "$" matches the end of lines as well as the string. 
       88      S  DOTALL      "." matches any character at all, including the newline. 
       89      X  VERBOSE     Ignore whitespace and comments for nicer looking RE's. 
       90      U  UNICODE     Make \w, \W, \b, \B, dependent on the Unicode locale. 
       91   
       92  This module also defines an exception 'error'. 
       93   
       94  """ 
       95   
       96  import sys 
       97  import sre_compile 
       98  import sre_parse 
       99   
      100  # public symbols 
      101  __all__ = [ "match", "search", "sub", "subn", "split", "findall", 
      102      "compile", "purge", "template", "escape", "I", "L", "M", "S", "X", 
      103      "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", 
      104      "UNICODE", "error" ] 
      105   
      106  __version__ = "2.2.1" 
      107   
      108  # flags 
      109  I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case 
      110  L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale 
      111  U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale 
      112  M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline 
      113  S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline 
      114  X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments 
      115   
      116  # sre extensions (experimental, don't rely on these) 
      117  T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking 
      118  DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation 
      119   
      120  # sre exception 
      121  error = sre_compile.error 
      122   
      123  # -------------------------------------------------------------------- 
      124  # public interface 
      125   
      
      126 -def match(pattern, string, flags=0):
      127 """Try to apply the pattern at the start of the string, returning 128 a match object, or None if no match was found.""" 129 return _compile(pattern, flags).match(string)
      130
      131 -def search(pattern, string, flags=0):
      132 """Scan through string looking for a match to the pattern, returning 133 a match object, or None if no match was found.""" 134 return _compile(pattern, flags).search(string)
      135
      136 -def sub(pattern, repl, string, count=0):
      137 """Return the string obtained by replacing the leftmost 138 non-overlapping occurrences of the pattern in string by the 139 replacement repl. repl can be either a string or a callable; 140 if a callable, it's passed the match object and must return 141 a replacement string to be used.""" 142 return _compile(pattern, 0).sub(repl, string, count)
      143
      144 -def subn(pattern, repl, string, count=0):
      145 """Return a 2-tuple containing (new_string, number). 146 new_string is the string obtained by replacing the leftmost 147 non-overlapping occurrences of the pattern in the source 148 string by the replacement repl. number is the number of 149 substitutions that were made. repl can be either a string or a 150 callable; if a callable, it's passed the match object and must 151 return a replacement string to be used.""" 152 return _compile(pattern, 0).subn(repl, string, count)
      153
      154 -def split(pattern, string, maxsplit=0):
      155 """Split the source string by the occurrences of the pattern, 156 returning a list containing the resulting substrings.""" 157 return _compile(pattern, 0).split(string, maxsplit)
      158
      159 -def findall(pattern, string, flags=0):
      160 """Return a list of all non-overlapping matches in the string. 161 162 If one or more groups are present in the pattern, return a 163 list of groups; this will be a list of tuples if the pattern 164 has more than one group. 165 166 Empty matches are included in the result.""" 167 return _compile(pattern, flags).findall(string)
      168 169 if sys.hexversion >= 0x02020000: 170 __all__.append("finditer")
      171 - def finditer(pattern, string, flags=0):
      172 """Return an iterator over all non-overlapping matches in the 173 string. For each match, the iterator returns a match object. 174 175 Empty matches are included in the result.""" 176 return _compile(pattern, flags).finditer(string)
      177
      178 -def compile(pattern, flags=0):
      179 "Compile a regular expression pattern, returning a pattern object." 180 return _compile(pattern, flags)
      181
      182 -def purge():
      183 "Clear the regular expression cache" 184 _cache.clear() 185 _cache_repl.clear()
      186
      187 -def template(pattern, flags=0):
      188 "Compile a template pattern, returning a pattern object" 189 return _compile(pattern, flags|T)
      190
      191 -def escape(pattern):
      192 "Escape all non-alphanumeric characters in pattern." 193 s = list(pattern) 194 for i in range(len(pattern)): 195 c = pattern[i] 196 if not ("a" <= c <= "z" or "A" <= c <= "Z" or "0" <= c <= "9"): 197 if c == "\000": 198 s[i] = "\\000" 199 else: 200 s[i] = "\\" + c 201 return pattern[:0].join(s)
      202 203 # -------------------------------------------------------------------- 204 # internals 205 206 _cache = {} 207 _cache_repl = {} 208 209 _pattern_type = type(sre_compile.compile("", 0)) 210 211 _MAXCACHE = 100 212
      213 -def _compile(*key):
      214 # internal: compile pattern 215 cachekey = (type(key[0]),) + key 216 p = _cache.get(cachekey) 217 if p is not None: 218 return p 219 pattern, flags = key 220 if isinstance(pattern, _pattern_type): 221 return pattern 222 if not sre_compile.isstring(pattern): 223 raise TypeError, "first argument must be string or compiled pattern" 224 try: 225 p = sre_compile.compile(pattern, flags) 226 except error, v: 227 raise error, v # invalid expression 228 if len(_cache) >= _MAXCACHE: 229 _cache.clear() 230 _cache[cachekey] = p 231 return p
      232
      233 -def _compile_repl(*key):
      234 # internal: compile replacement pattern 235 p = _cache_repl.get(key) 236 if p is not None: 237 return p 238 repl, pattern = key 239 try: 240 p = sre_parse.parse_template(repl, pattern) 241 except error, v: 242 raise error, v # invalid expression 243 if len(_cache_repl) >= _MAXCACHE: 244 _cache_repl.clear() 245 _cache_repl[key] = p 246 return p
      247
      248 -def _expand(pattern, match, template):
      249 # internal: match.expand implementation hook 250 template = sre_parse.parse_template(template, pattern) 251 return sre_parse.expand_template(template, match)
      252
      253 -def _subx(pattern, template):
      254 # internal: pattern.sub/subn implementation helper 255 template = _compile_repl(template, pattern) 256 if not template[0] and len(template[1]) == 1: 257 # literal replacement 258 return template[1][0] 259 def filter(match, template=template): 260 return sre_parse.expand_template(template, match)
      261 return filter
      262 263 # register myself for pickling 264 265 import copy_reg 266
      267 -def _pickle(p):
      268 return _compile, (p.pattern, p.flags)
      269 270 copy_reg.pickle(_pattern_type, _pickle, _compile) 271 272 # -------------------------------------------------------------------- 273 # experimental stuff (see python-dev discussions for details) 274
      275 -class Scanner:
      276 - def __init__(self, lexicon, flags=0):
      277 from sre_constants import BRANCH, SUBPATTERN 278 self.lexicon = lexicon 279 # combine phrases into a compound pattern 280 p = [] 281 s = sre_parse.Pattern() 282 s.flags = flags 283 for phrase, action in lexicon: 284 p.append(sre_parse.SubPattern(s, [ 285 (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), 286 ])) 287 p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) 288 s.groups = len(p) 289 self.scanner = sre_compile.compile(p)
      290 - def scan(self, string):
      291 result = [] 292 append = result.append 293 match = self.scanner.scanner(string).match 294 i = 0 295 while 1: 296 m = match() 297 if not m: 298 break 299 j = m.end() 300 if i == j: 301 break 302 action = self.lexicon[m.lastindex-1][1] 303 if callable(action): 304 self.match = m 305 action = action(self, m.group()) 306 if action is not None: 307 append(action) 308 i = j 309 return result, string[i:]
      310

      epydoc-3.0.1+dfsg/doc/examples/toc.html0000644000175000017500000000262210750103050020224 0ustar pronovicpronovic Table of Contents

      Table of Contents


      Everything

      Modules

      epytext_example
      sre

      [hide private] epydoc-3.0.1+dfsg/doc/examples/identifier-index.html0000644000175000017500000004025510750103050022672 0ustar pronovicpronovic Identifier Index
       
      [hide private]
      [frames] | no frames]
      [ Identifiers | Term Definitions ]

      Identifier Index

      [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

      C

      D

      E

      F

      I

      L

      M

      P

      S

      T

      U

      V

      X

      Z

      _



      epydoc-3.0.1+dfsg/doc/examples/sre_constants.error-class.html0000644000175000017500000001212210750103050024553 0ustar pronovicpronovic sre_constants.error
      sre_constants :: error :: Class error
      [hide private]
      [frames] | no frames]

      Class error

      exceptions.Exception --+
                             |
                            error
      

      Instance Methods [hide private]

      Inherited from exceptions.Exception: __getitem__, __init__, __str__

      epydoc-3.0.1+dfsg/doc/examples/included/0002755000175000017500000000000010750103105020341 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/examples/included/inh_example-module.html0000644000175000017500000001521110750103050025000 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Module inh_example

      source code

      Examples for the epytext manual.

      Classes [hide private]
        Animal
        Bug
        Bird
        Fish
        Mammal
        Primate
        Human
        Programmer
      epydoc-3.0.1+dfsg/doc/examples/included/toc.html0000644000175000017500000000236710750103050022021 0ustar pronovicpronovic Table of Contents

      Table of Contents


      Everything

      Modules

      inh_example

      [hide private] epydoc-3.0.1+dfsg/doc/examples/included/identifier-index.html0000644000175000017500000003142610750103050024461 0ustar pronovicpronovic Identifier Index
       
      [hide private]
      [frames] | no frames]

      Identifier Index

      [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

      A

      B

      C

      E

      F

      G

      H

      I

      M

      P

      R

      S

      T



      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Programmer-class.html0000644000175000017500000003225410750103050026740 0ustar pronovicpronovic inh_example.Programmer
      Module inh_example :: Class Programmer
      [hide private]
      [frames] | no frames]

      Class Programmer

      source code

      Animal --+            
               |            
          Mammal --+        
                   |        
             Primate --+    
                       |    
                   Human --+
                           |
                          Programmer
      

      Instance Methods [hide private]
       
      hack(self, code)
      Improve the given program.
      source code
       
      squish(self, bug, code)
      Remove the given bug from the given program.
      source code
       
      climb(self, tree)
      Climb up the given tree. (Inherited from inh_example.Primate)
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      grab(self, object)
      Grab hold of the given object. (Inherited from inh_example.Primate)
      source code
       
      run(self, dest)
      Run to the given destination. (Inherited from inh_example.Mammal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
       
      talk(self, animal)
      Talk to the given animal. (Inherited from inh_example.Human)
      source code
      Method Details [hide private]

      squish(self, bug, code)

      source code 

      Remove the given bug from the given program.

      Parameters:
      • bug (Bug) - The bug that should be removed from code.

      epydoc-3.0.1+dfsg/doc/examples/included/toc-inh_example-module.html0000644000175000017500000000322010750103050025560 0ustar pronovicpronovic inh_example

      Module inh_example


      Classes

      Animal
      Bird
      Bug
      Fish
      Human
      Mammal
      Primate
      Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/included/toc-everything.html0000644000175000017500000000335310750103050024177 0ustar pronovicpronovic Everything

      Everything


      All Classes

      inh_example.Animal
      inh_example.Bird
      inh_example.Bug
      inh_example.Fish
      inh_example.Human
      inh_example.Mammal
      inh_example.Primate
      inh_example.Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/included/module-tree.html0000644000175000017500000001014610750103050023450 0ustar pronovicpronovic Module Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Module Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/included/inh_example-pysrc.html0000644000175000017500000004557510750103050024673 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Source Code for Module inh_example

       1  # 
       2  # inh_example.py 
       3  # 
       4  # Example code used by the epytext manual. 
       5  # 
       6  # These classes are used to illustrate the different inheritance 
       7  # styles. (grouped, listed, and included). 
       8  # 
       9  """ 
      10  Examples for the epytext manual. 
      11  """ 
      12  __docformat__='epytext' 
      13   
      
      14 -class Animal:
      15 - def eat(self, food): "Consume the given food object."
      16 - def sleep(self, time): "Sleep for the given period of time."
      17
      18 -class Bug(Animal):
      19 - def infest(self, code): "Add new bugs to the given program."
      20 - def hide(self):
      21 """ 22 Temporarily stop breaking a program, in order to evade 23 capture. 24 """
      25 -class Bird(Animal):
      26 - def fly(self, dest): "Fly to the given destination."
      27
      28 -class Fish(Animal):
      29 - def swim(self, dest): "Swim to the given destination."
      30
      31 -class Mammal(Animal):
      32 - def run(self, dest): "Run to the given destination."
      33
      34 -class Primate(Mammal):
      35 - def climb(self, tree): "Climb up the given tree."
      36 - def grab(self, object): "Grab hold of the given object."
      37
      38 -class Human(Primate):
      39 - def talk(self, animal):
      40 """ 41 Talk to the given animal. Depending on what kind of creature 42 C{animal} is, it may or may not be responsive. 43 """
      44
      45 -class Programmer(Human):
      46 - def hack(self, code): "Improve the given program."
      47 - def squish(self, bug, code):
      48 """ 49 Remove the given bug from the given program. 50 @type bug: L{Bug} 51 @param bug: The bug that should be removed from C{code}. 52 """
      53

      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Bug-class.html0000644000175000017500000001761710750103050025350 0ustar pronovicpronovic inh_example.Bug
      Module inh_example :: Class Bug
      [hide private]
      [frames] | no frames]

      Class Bug

      source code

      Animal --+
               |
              Bug
      

      Instance Methods [hide private]
       
      infest(self, code)
      Add new bugs to the given program.
      source code
       
      hide(self)
      Temporarily stop breaking a program, in order to evade capture.
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      epydoc-3.0.1+dfsg/doc/examples/included/class-tree.html0000644000175000017500000001164110750103050023271 0ustar pronovicpronovic Class Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Class Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Human-class.html0000644000175000017500000002660110750103050025674 0ustar pronovicpronovic inh_example.Human
      Module inh_example :: Class Human
      [hide private]
      [frames] | no frames]

      Class Human

      source code

      Animal --+        
               |        
          Mammal --+    
                   |    
             Primate --+
                       |
                      Human
      
      Known Subclasses:

      Instance Methods [hide private]
       
      talk(self, animal)
      Talk to the given animal.
      source code
       
      climb(self, tree)
      Climb up the given tree. (Inherited from inh_example.Primate)
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      grab(self, object)
      Grab hold of the given object. (Inherited from inh_example.Primate)
      source code
       
      run(self, dest)
      Run to the given destination. (Inherited from inh_example.Mammal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      Method Details [hide private]

      talk(self, animal)

      source code 

      Talk to the given animal. Depending on what kind of creature animal is, it may or may not be responsive.


      epydoc-3.0.1+dfsg/doc/examples/included/epydoc.css0000644000175000017500000003722710750103050022346 0ustar pronovicpronovic /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: #ffffff; color: #000000; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: #0000ff; } a:visited { color: #204080; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

      ). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } epydoc-3.0.1+dfsg/doc/examples/included/help.html0000644000175000017500000002601310750103050022156 0ustar pronovicpronovic Help
       
      [hide private]
      [frames] | no frames]

      API Documentation

      This document contains the API (Application Programming Interface) documentation for epydoc. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

      Object Documentation

      Each Package Documentation page contains:

      • A description of the package.
      • A list of the modules and sub-packages contained by the package.
      • A summary of the classes defined by the package.
      • A summary of the functions defined by the package.
      • A summary of the variables defined by the package.
      • A detailed description of each function defined by the package.
      • A detailed description of each variable defined by the package.

      Each Module Documentation page contains:

      • A description of the module.
      • A summary of the classes defined by the module.
      • A summary of the functions defined by the module.
      • A summary of the variables defined by the module.
      • A detailed description of each function defined by the module.
      • A detailed description of each variable defined by the module.

      Each Class Documentation page contains:

      • A class inheritance diagram.
      • A list of known subclasses.
      • A description of the class.
      • A summary of the methods defined by the class.
      • A summary of the instance variables defined by the class.
      • A summary of the class (static) variables defined by the class.
      • A detailed description of each method defined by the class.
      • A detailed description of each instance variable defined by the class.
      • A detailed description of each class (static) variable defined by the class.

      Project Documentation

      The Trees page contains the module and class hierarchies:

      • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
      • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

      The Index page contains indices of terms and identifiers:

      • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
      • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

      The Table of Contents

      The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

      Project
      Contents
      ...
      API
      Documentation
      Frame


      Module
      Contents
       
      ...
       

      The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

      The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

      The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

      The Navigation Bar

      A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

      Label Highlighted when... Links to...
      [Parent] (never highlighted) the parent of the current package
      [Package] viewing a package the package containing the current object
      [Module] viewing a module the module containing the current object
      [Class] viewing a class the class containing the current object
      [Trees] viewing the trees page the trees page
      [Index] viewing the index page the index page
      [Help] viewing the help page the help page

      The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

      A timestamp below the bottom navigation bar indicates when each page was last updated.

      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Bird-class.html0000644000175000017500000001632410750103050025505 0ustar pronovicpronovic inh_example.Bird
      Module inh_example :: Class Bird
      [hide private]
      [frames] | no frames]

      Class Bird

      source code

      Animal --+
               |
              Bird
      

      Instance Methods [hide private]
       
      fly(self, dest)
      Fly to the given destination.
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      epydoc-3.0.1+dfsg/doc/examples/included/frames.html0000644000175000017500000000110610750103050022477 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/included/redirect.html0000644000175000017500000000225010750103050023024 0ustar pronovicpronovicEpydoc Redirect Page

      Epydoc Auto-redirect page

      When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

       

      epydoc-3.0.1+dfsg/doc/examples/included/index.html0000644000175000017500000000110610750103050022331 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Mammal-class.html0000644000175000017500000001657010750103050026034 0ustar pronovicpronovic inh_example.Mammal
      Module inh_example :: Class Mammal
      [hide private]
      [frames] | no frames]

      Class Mammal

      source code

      Animal --+
               |
              Mammal
      
      Known Subclasses:

      Instance Methods [hide private]
       
      run(self, dest)
      Run to the given destination.
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Fish-class.html0000644000175000017500000001633010750103050025513 0ustar pronovicpronovic inh_example.Fish
      Module inh_example :: Class Fish
      [hide private]
      [frames] | no frames]

      Class Fish

      source code

      Animal --+
               |
              Fish
      

      Instance Methods [hide private]
       
      swim(self, dest)
      Swim to the given destination.
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Animal-class.html0000644000175000017500000001501110750103050026016 0ustar pronovicpronovic inh_example.Animal
      Module inh_example :: Class Animal
      [hide private]
      [frames] | no frames]

      Class Animal

      source code

      Known Subclasses:

      Instance Methods [hide private]
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/included/crarr.png0000644000175000017500000000052410750103050022156 0ustar pronovicpronovic‰PNG  IHDR e¢E,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIMEÖ)Ó}Ö pHYsÂÂnÐu>gAMA± üaEPLTEÿÿÿÍð×ÏÀ€f4sW áÛЊrD`@bCÜÕÈéäÜ–X{`,¯Ÿ€lN‡o@õóðª™xdEðí螊dÐÆ´”~TÖwÅvtRNS@æØfMIDATxÚc`@¼ì¼0&+š—Šˆ°»(’ˆ€ ;; /ðEXùØ‘?Ð n ƒª†— b;'ª+˜˜YÐ#œ(r<£"IEND®B`‚epydoc-3.0.1+dfsg/doc/examples/included/inh_example.Primate-class.html0000644000175000017500000002170210750103050026222 0ustar pronovicpronovic inh_example.Primate
      Module inh_example :: Class Primate
      [hide private]
      [frames] | no frames]

      Class Primate

      source code

      Animal --+    
               |    
          Mammal --+
                   |
                  Primate
      
      Known Subclasses:

      Instance Methods [hide private]
       
      climb(self, tree)
      Climb up the given tree.
      source code
       
      grab(self, object)
      Grab hold of the given object.
      source code
       
      eat(self, food)
      Consume the given food object. (Inherited from inh_example.Animal)
      source code
       
      run(self, dest)
      Run to the given destination. (Inherited from inh_example.Mammal)
      source code
       
      sleep(self, time)
      Sleep for the given period of time. (Inherited from inh_example.Animal)
      source code
      epydoc-3.0.1+dfsg/doc/examples/toc-everything.html0000644000175000017500000001105710750103050022410 0ustar pronovicpronovic Everything

      Everything


      All Classes

      sre_constants.error

      All Functions

      epytext_example.x_intercept
      epytext_example.z_transform
      sre.compile
      sre.escape
      sre.findall
      sre.finditer
      sre.match
      sre.purge
      sre.search
      sre.split
      sre.sub
      sre.subn
      sre.template

      All Variables

      sre.DOTALL
      sre.I
      sre.IGNORECASE
      sre.L
      sre.LOCALE
      sre.M
      sre.MULTILINE
      sre.S
      sre.U
      sre.UNICODE
      sre.VERBOSE
      sre.X

      [hide private] epydoc-3.0.1+dfsg/doc/examples/module-tree.html0000644000175000017500000001041310750103050021656 0ustar pronovicpronovic Module Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Module Hierarchy

      • epytext_example: Examples for the epytext manual.
      • sre: Support for regular expressions (RE).
      epydoc-3.0.1+dfsg/doc/examples/grouped/0002755000175000017500000000000010750103105020217 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/examples/grouped/inh_example-module.html0000644000175000017500000001521110750103050024656 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Module inh_example

      source code

      Examples for the epytext manual.

      Classes [hide private]
        Animal
        Bug
        Bird
        Fish
        Mammal
        Primate
        Human
        Programmer
      epydoc-3.0.1+dfsg/doc/examples/grouped/toc.html0000644000175000017500000000236710750103050021677 0ustar pronovicpronovic Table of Contents

      Table of Contents


      Everything

      Modules

      inh_example

      [hide private] epydoc-3.0.1+dfsg/doc/examples/grouped/identifier-index.html0000644000175000017500000003142610750103050024337 0ustar pronovicpronovic Identifier Index
       
      [hide private]
      [frames] | no frames]

      Identifier Index

      [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

      A

      B

      C

      E

      F

      G

      H

      I

      M

      P

      R

      S

      T



      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Programmer-class.html0000644000175000017500000003242010750103050026611 0ustar pronovicpronovic inh_example.Programmer
      Module inh_example :: Class Programmer
      [hide private]
      [frames] | no frames]

      Class Programmer

      source code

      Animal --+            
               |            
          Mammal --+        
                   |        
             Primate --+    
                       |    
                   Human --+
                           |
                          Programmer
      

      Instance Methods [hide private]
       
      hack(self, code)
      Improve the given program.
      source code
       
      squish(self, bug, code)
      Remove the given bug from the given program.
      source code
          Inherited from Human
       
      talk(self, animal)
      Talk to the given animal.
      source code
          Inherited from Primate
       
      climb(self, tree)
      Climb up the given tree.
      source code
       
      grab(self, object)
      Grab hold of the given object.
      source code
          Inherited from Mammal
       
      run(self, dest)
      Run to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      Method Details [hide private]

      squish(self, bug, code)

      source code 

      Remove the given bug from the given program.

      Parameters:
      • bug (Bug) - The bug that should be removed from code.

      epydoc-3.0.1+dfsg/doc/examples/grouped/toc-inh_example-module.html0000644000175000017500000000322010750103050025436 0ustar pronovicpronovic inh_example

      Module inh_example


      Classes

      Animal
      Bird
      Bug
      Fish
      Human
      Mammal
      Primate
      Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/grouped/toc-everything.html0000644000175000017500000000335310750103050024055 0ustar pronovicpronovic Everything

      Everything


      All Classes

      inh_example.Animal
      inh_example.Bird
      inh_example.Bug
      inh_example.Fish
      inh_example.Human
      inh_example.Mammal
      inh_example.Primate
      inh_example.Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/grouped/module-tree.html0000644000175000017500000001014610750103050023326 0ustar pronovicpronovic Module Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Module Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example-pysrc.html0000644000175000017500000004557510750103050024551 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Source Code for Module inh_example

       1  # 
       2  # inh_example.py 
       3  # 
       4  # Example code used by the epytext manual. 
       5  # 
       6  # These classes are used to illustrate the different inheritance 
       7  # styles. (grouped, listed, and included). 
       8  # 
       9  """ 
      10  Examples for the epytext manual. 
      11  """ 
      12  __docformat__='epytext' 
      13   
      
      14 -class Animal:
      15 - def eat(self, food): "Consume the given food object."
      16 - def sleep(self, time): "Sleep for the given period of time."
      17
      18 -class Bug(Animal):
      19 - def infest(self, code): "Add new bugs to the given program."
      20 - def hide(self):
      21 """ 22 Temporarily stop breaking a program, in order to evade 23 capture. 24 """
      25 -class Bird(Animal):
      26 - def fly(self, dest): "Fly to the given destination."
      27
      28 -class Fish(Animal):
      29 - def swim(self, dest): "Swim to the given destination."
      30
      31 -class Mammal(Animal):
      32 - def run(self, dest): "Run to the given destination."
      33
      34 -class Primate(Mammal):
      35 - def climb(self, tree): "Climb up the given tree."
      36 - def grab(self, object): "Grab hold of the given object."
      37
      38 -class Human(Primate):
      39 - def talk(self, animal):
      40 """ 41 Talk to the given animal. Depending on what kind of creature 42 C{animal} is, it may or may not be responsive. 43 """
      44
      45 -class Programmer(Human):
      46 - def hack(self, code): "Improve the given program."
      47 - def squish(self, bug, code):
      48 """ 49 Remove the given bug from the given program. 50 @type bug: L{Bug} 51 @param bug: The bug that should be removed from C{code}. 52 """
      53

      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Bug-class.html0000644000175000017500000001757110750103050025225 0ustar pronovicpronovic inh_example.Bug
      Module inh_example :: Class Bug
      [hide private]
      [frames] | no frames]

      Class Bug

      source code

      Animal --+
               |
              Bug
      

      Instance Methods [hide private]
       
      infest(self, code)
      Add new bugs to the given program.
      source code
       
      hide(self)
      Temporarily stop breaking a program, in order to evade capture.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/grouped/class-tree.html0000644000175000017500000001164110750103050023147 0ustar pronovicpronovic Class Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Class Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Human-class.html0000644000175000017500000002663410750103050025560 0ustar pronovicpronovic inh_example.Human
      Module inh_example :: Class Human
      [hide private]
      [frames] | no frames]

      Class Human

      source code

      Animal --+        
               |        
          Mammal --+    
                   |    
             Primate --+
                       |
                      Human
      
      Known Subclasses:

      Instance Methods [hide private]
       
      talk(self, animal)
      Talk to the given animal.
      source code
          Inherited from Primate
       
      climb(self, tree)
      Climb up the given tree.
      source code
       
      grab(self, object)
      Grab hold of the given object.
      source code
          Inherited from Mammal
       
      run(self, dest)
      Run to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      Method Details [hide private]

      talk(self, animal)

      source code 

      Talk to the given animal. Depending on what kind of creature animal is, it may or may not be responsive.


      epydoc-3.0.1+dfsg/doc/examples/grouped/epydoc.css0000644000175000017500000003722710750103050022224 0ustar pronovicpronovic /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: #ffffff; color: #000000; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: #0000ff; } a:visited { color: #204080; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

      ). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } epydoc-3.0.1+dfsg/doc/examples/grouped/help.html0000644000175000017500000002601310750103050022034 0ustar pronovicpronovic Help
       
      [hide private]
      [frames] | no frames]

      API Documentation

      This document contains the API (Application Programming Interface) documentation for epydoc. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

      Object Documentation

      Each Package Documentation page contains:

      • A description of the package.
      • A list of the modules and sub-packages contained by the package.
      • A summary of the classes defined by the package.
      • A summary of the functions defined by the package.
      • A summary of the variables defined by the package.
      • A detailed description of each function defined by the package.
      • A detailed description of each variable defined by the package.

      Each Module Documentation page contains:

      • A description of the module.
      • A summary of the classes defined by the module.
      • A summary of the functions defined by the module.
      • A summary of the variables defined by the module.
      • A detailed description of each function defined by the module.
      • A detailed description of each variable defined by the module.

      Each Class Documentation page contains:

      • A class inheritance diagram.
      • A list of known subclasses.
      • A description of the class.
      • A summary of the methods defined by the class.
      • A summary of the instance variables defined by the class.
      • A summary of the class (static) variables defined by the class.
      • A detailed description of each method defined by the class.
      • A detailed description of each instance variable defined by the class.
      • A detailed description of each class (static) variable defined by the class.

      Project Documentation

      The Trees page contains the module and class hierarchies:

      • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
      • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

      The Index page contains indices of terms and identifiers:

      • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
      • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

      The Table of Contents

      The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

      Project
      Contents
      ...
      API
      Documentation
      Frame


      Module
      Contents
       
      ...
       

      The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

      The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

      The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

      The Navigation Bar

      A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

      Label Highlighted when... Links to...
      [Parent] (never highlighted) the parent of the current package
      [Package] viewing a package the package containing the current object
      [Module] viewing a module the module containing the current object
      [Class] viewing a class the class containing the current object
      [Trees] viewing the trees page the trees page
      [Index] viewing the index page the index page
      [Help] viewing the help page the help page

      The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

      A timestamp below the bottom navigation bar indicates when each page was last updated.

      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Bird-class.html0000644000175000017500000001627610750103050025371 0ustar pronovicpronovic inh_example.Bird
      Module inh_example :: Class Bird
      [hide private]
      [frames] | no frames]

      Class Bird

      source code

      Animal --+
               |
              Bird
      

      Instance Methods [hide private]
       
      fly(self, dest)
      Fly to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/grouped/frames.html0000644000175000017500000000110610750103050022355 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/grouped/redirect.html0000644000175000017500000000225010750103050022702 0ustar pronovicpronovicEpydoc Redirect Page

      Epydoc Auto-redirect page

      When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

       

      epydoc-3.0.1+dfsg/doc/examples/grouped/index.html0000644000175000017500000000110610750103050022207 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Mammal-class.html0000644000175000017500000001654210750103050025711 0ustar pronovicpronovic inh_example.Mammal
      Module inh_example :: Class Mammal
      [hide private]
      [frames] | no frames]

      Class Mammal

      source code

      Animal --+
               |
              Mammal
      
      Known Subclasses:

      Instance Methods [hide private]
       
      run(self, dest)
      Run to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Fish-class.html0000644000175000017500000001630210750103050025370 0ustar pronovicpronovic inh_example.Fish
      Module inh_example :: Class Fish
      [hide private]
      [frames] | no frames]

      Class Fish

      source code

      Animal --+
               |
              Fish
      

      Instance Methods [hide private]
       
      swim(self, dest)
      Swim to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Animal-class.html0000644000175000017500000001501110750103050025674 0ustar pronovicpronovic inh_example.Animal
      Module inh_example :: Class Animal
      [hide private]
      [frames] | no frames]

      Class Animal

      source code

      Known Subclasses:

      Instance Methods [hide private]
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/grouped/crarr.png0000644000175000017500000000052410750103050022034 0ustar pronovicpronovic‰PNG  IHDR e¢E,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIMEÖ)Ó}Ö pHYsÂÂnÐu>gAMA± üaEPLTEÿÿÿÍð×ÏÀ€f4sW áÛЊrD`@bCÜÕÈéäÜ–X{`,¯Ÿ€lN‡o@õóðª™xdEðí螊dÐÆ´”~TÖwÅvtRNS@æØfMIDATxÚc`@¼ì¼0&+š—Šˆ°»(’ˆ€ ;; /ðEXùØ‘?Ð n ƒª†— b;'ª+˜˜YÐ#œ(r<£"IEND®B`‚epydoc-3.0.1+dfsg/doc/examples/grouped/inh_example.Primate-class.html0000644000175000017500000002176510750103050026111 0ustar pronovicpronovic inh_example.Primate
      Module inh_example :: Class Primate
      [hide private]
      [frames] | no frames]

      Class Primate

      source code

      Animal --+    
               |    
          Mammal --+
                   |
                  Primate
      
      Known Subclasses:

      Instance Methods [hide private]
       
      climb(self, tree)
      Climb up the given tree.
      source code
       
      grab(self, object)
      Grab hold of the given object.
      source code
          Inherited from Mammal
       
      run(self, dest)
      Run to the given destination.
      source code
          Inherited from Animal
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/epytext_example-module.html0000644000175000017500000002076610750103050024150 0ustar pronovicpronovic epytext_example
      Module epytext_example
      [hide private]
      [frames] | no frames]

      Module epytext_example

      source code

      Examples for the epytext manual.

      Functions [hide private]
      number
      x_intercept(m, b)
      Return the x intercept of the line y=m*x+b.
      source code
       
      z_transform(f)
      This is just an example; there is no z_transform function.
      source code
      Function Details [hide private]

      x_intercept(m, b)

      source code 

      Return the x intercept of the line y=m*x+b. The x intercept of a line is the point at which it crosses the x axis (y=0).

      This function can be used in conjuction with z_transform to find an arbitrary function's zeros.

      Parameters:
      • m (number) - The slope of the line.
      • b (number) - The y intercept of the line. The y intercept of a line is the point at which it crosses the y axis (x=0).
      Returns: number
      the x intercept of the line y=m*x+b.

      epydoc-3.0.1+dfsg/doc/examples/class-tree.html0000644000175000017500000001054110750103050021500 0ustar pronovicpronovic Class Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Class Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/epydoc.css0000644000175000017500000003722710750103050020557 0ustar pronovicpronovic /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: #ffffff; color: #000000; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: #0000ff; } a:visited { color: #204080; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

      ). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } epydoc-3.0.1+dfsg/doc/examples/help.html0000644000175000017500000002602310750103050020370 0ustar pronovicpronovic Help
       
      [hide private]
      [frames] | no frames]

      API Documentation

      This document contains the API (Application Programming Interface) documentation for epydoc. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

      Object Documentation

      Each Package Documentation page contains:

      • A description of the package.
      • A list of the modules and sub-packages contained by the package.
      • A summary of the classes defined by the package.
      • A summary of the functions defined by the package.
      • A summary of the variables defined by the package.
      • A detailed description of each function defined by the package.
      • A detailed description of each variable defined by the package.

      Each Module Documentation page contains:

      • A description of the module.
      • A summary of the classes defined by the module.
      • A summary of the functions defined by the module.
      • A summary of the variables defined by the module.
      • A detailed description of each function defined by the module.
      • A detailed description of each variable defined by the module.

      Each Class Documentation page contains:

      • A class inheritance diagram.
      • A list of known subclasses.
      • A description of the class.
      • A summary of the methods defined by the class.
      • A summary of the instance variables defined by the class.
      • A summary of the class (static) variables defined by the class.
      • A detailed description of each method defined by the class.
      • A detailed description of each instance variable defined by the class.
      • A detailed description of each class (static) variable defined by the class.

      Project Documentation

      The Trees page contains the module and class hierarchies:

      • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
      • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

      The Index page contains indices of terms and identifiers:

      • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
      • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

      The Table of Contents

      The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

      Project
      Contents
      ...
      API
      Documentation
      Frame


      Module
      Contents
       
      ...
       

      The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

      The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

      The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

      The Navigation Bar

      A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

      Label Highlighted when... Links to...
      [Parent] (never highlighted) the parent of the current package
      [Package] viewing a package the package containing the current object
      [Module] viewing a module the module containing the current object
      [Class] viewing a class the class containing the current object
      [Trees] viewing the trees page the trees page
      [Index] viewing the index page the index page
      [Help] viewing the help page the help page

      The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

      A timestamp below the bottom navigation bar indicates when each page was last updated.

      epydoc-3.0.1+dfsg/doc/examples/toc-epytext_example-module.html0000644000175000017500000000230010750103050024713 0ustar pronovicpronovic epytext_example

      Module epytext_example


      Functions

      x_intercept
      z_transform

      [hide private] epydoc-3.0.1+dfsg/doc/examples/toc-sre-module.html0000644000175000017500000001023210750103050022272 0ustar pronovicpronovic sre

      Module sre


      Classes

      error

      Functions

      compile
      escape
      findall
      finditer
      match
      purge
      search
      split
      sub
      subn
      template

      Variables

      DOTALL
      I
      IGNORECASE
      L
      LOCALE
      M
      MULTILINE
      S
      T
      U
      UNICODE
      VERBOSE
      X

      [hide private] epydoc-3.0.1+dfsg/doc/examples/frames.html0000644000175000017500000000111210750103050020705 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/redirect.html0000644000175000017500000000204210750103050021234 0ustar pronovicpronovicEpydoc Redirect Page

      Epydoc Auto-redirect page

      When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

       

      epydoc-3.0.1+dfsg/doc/examples/index.html0000644000175000017500000000111210750103050020537 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/listed/0002755000175000017500000000000010750103105020036 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/examples/listed/inh_example-module.html0000644000175000017500000001521110750103050024475 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Module inh_example

      source code

      Examples for the epytext manual.

      Classes [hide private]
        Animal
        Bug
        Bird
        Fish
        Mammal
        Primate
        Human
        Programmer
      epydoc-3.0.1+dfsg/doc/examples/listed/toc.html0000644000175000017500000000236710750103050021516 0ustar pronovicpronovic Table of Contents

      Table of Contents


      Everything

      Modules

      inh_example

      [hide private] epydoc-3.0.1+dfsg/doc/examples/listed/identifier-index.html0000644000175000017500000003142610750103050024156 0ustar pronovicpronovic Identifier Index
       
      [hide private]
      [frames] | no frames]

      Identifier Index

      [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

      A

      B

      C

      E

      F

      G

      H

      I

      M

      P

      R

      S

      T



      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Programmer-class.html0000644000175000017500000002267310750103050026441 0ustar pronovicpronovic inh_example.Programmer
      Module inh_example :: Class Programmer
      [hide private]
      [frames] | no frames]

      Class Programmer

      source code

      Animal --+            
               |            
          Mammal --+        
                   |        
             Primate --+    
                       |    
                   Human --+
                           |
                          Programmer
      

      Instance Methods [hide private]
       
      hack(self, code)
      Improve the given program.
      source code
       
      squish(self, bug, code)
      Remove the given bug from the given program.
      source code

      Inherited from Human: talk

      Inherited from Primate: climb, grab

      Inherited from Mammal: run

      Inherited from Animal: eat, sleep

      Method Details [hide private]

      squish(self, bug, code)

      source code 

      Remove the given bug from the given program.

      Parameters:
      • bug (Bug) - The bug that should be removed from code.

      epydoc-3.0.1+dfsg/doc/examples/listed/toc-inh_example-module.html0000644000175000017500000000322010750103050025255 0ustar pronovicpronovic inh_example

      Module inh_example


      Classes

      Animal
      Bird
      Bug
      Fish
      Human
      Mammal
      Primate
      Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/listed/toc-everything.html0000644000175000017500000000335310750103050023674 0ustar pronovicpronovic Everything

      Everything


      All Classes

      inh_example.Animal
      inh_example.Bird
      inh_example.Bug
      inh_example.Fish
      inh_example.Human
      inh_example.Mammal
      inh_example.Primate
      inh_example.Programmer

      [hide private] epydoc-3.0.1+dfsg/doc/examples/listed/module-tree.html0000644000175000017500000001014610750103050023145 0ustar pronovicpronovic Module Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Module Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example-pysrc.html0000644000175000017500000004557510750103050024370 0ustar pronovicpronovic inh_example
      Module inh_example
      [hide private]
      [frames] | no frames]

      Source Code for Module inh_example

       1  # 
       2  # inh_example.py 
       3  # 
       4  # Example code used by the epytext manual. 
       5  # 
       6  # These classes are used to illustrate the different inheritance 
       7  # styles. (grouped, listed, and included). 
       8  # 
       9  """ 
      10  Examples for the epytext manual. 
      11  """ 
      12  __docformat__='epytext' 
      13   
      
      14 -class Animal:
      15 - def eat(self, food): "Consume the given food object."
      16 - def sleep(self, time): "Sleep for the given period of time."
      17
      18 -class Bug(Animal):
      19 - def infest(self, code): "Add new bugs to the given program."
      20 - def hide(self):
      21 """ 22 Temporarily stop breaking a program, in order to evade 23 capture. 24 """
      25 -class Bird(Animal):
      26 - def fly(self, dest): "Fly to the given destination."
      27
      28 -class Fish(Animal):
      29 - def swim(self, dest): "Swim to the given destination."
      30
      31 -class Mammal(Animal):
      32 - def run(self, dest): "Run to the given destination."
      33
      34 -class Primate(Mammal):
      35 - def climb(self, tree): "Climb up the given tree."
      36 - def grab(self, object): "Grab hold of the given object."
      37
      38 -class Human(Primate):
      39 - def talk(self, animal):
      40 """ 41 Talk to the given animal. Depending on what kind of creature 42 C{animal} is, it may or may not be responsive. 43 """
      44
      45 -class Programmer(Human):
      46 - def hack(self, code): "Improve the given program."
      47 - def squish(self, bug, code):
      48 """ 49 Remove the given bug from the given program. 50 @type bug: L{Bug} 51 @param bug: The bug that should be removed from C{code}. 52 """
      53

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Bug-class.html0000644000175000017500000001522110750103050025032 0ustar pronovicpronovic inh_example.Bug
      Module inh_example :: Class Bug
      [hide private]
      [frames] | no frames]

      Class Bug

      source code

      Animal --+
               |
              Bug
      

      Instance Methods [hide private]
       
      infest(self, code)
      Add new bugs to the given program.
      source code
       
      hide(self)
      Temporarily stop breaking a program, in order to evade capture.
      source code

      Inherited from Animal: eat, sleep

      epydoc-3.0.1+dfsg/doc/examples/listed/class-tree.html0000644000175000017500000001164110750103050022766 0ustar pronovicpronovic Class Hierarchy
       
      [hide private]
      [frames] | no frames]
      [ Module Hierarchy | Class Hierarchy ]

      Class Hierarchy

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Human-class.html0000644000175000017500000002036610750103050025373 0ustar pronovicpronovic inh_example.Human
      Module inh_example :: Class Human
      [hide private]
      [frames] | no frames]

      Class Human

      source code

      Animal --+        
               |        
          Mammal --+    
                   |    
             Primate --+
                       |
                      Human
      
      Known Subclasses:

      Instance Methods [hide private]
       
      talk(self, animal)
      Talk to the given animal.
      source code

      Inherited from Primate: climb, grab

      Inherited from Mammal: run

      Inherited from Animal: eat, sleep

      Method Details [hide private]

      talk(self, animal)

      source code 

      Talk to the given animal. Depending on what kind of creature animal is, it may or may not be responsive.


      epydoc-3.0.1+dfsg/doc/examples/listed/epydoc.css0000644000175000017500000003722710750103050022043 0ustar pronovicpronovic /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: #ffffff; color: #000000; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: #0000ff; } a:visited { color: #204080; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

      ). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } epydoc-3.0.1+dfsg/doc/examples/listed/help.html0000644000175000017500000002601310750103050021653 0ustar pronovicpronovic Help
       
      [hide private]
      [frames] | no frames]

      API Documentation

      This document contains the API (Application Programming Interface) documentation for epydoc. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

      Object Documentation

      Each Package Documentation page contains:

      • A description of the package.
      • A list of the modules and sub-packages contained by the package.
      • A summary of the classes defined by the package.
      • A summary of the functions defined by the package.
      • A summary of the variables defined by the package.
      • A detailed description of each function defined by the package.
      • A detailed description of each variable defined by the package.

      Each Module Documentation page contains:

      • A description of the module.
      • A summary of the classes defined by the module.
      • A summary of the functions defined by the module.
      • A summary of the variables defined by the module.
      • A detailed description of each function defined by the module.
      • A detailed description of each variable defined by the module.

      Each Class Documentation page contains:

      • A class inheritance diagram.
      • A list of known subclasses.
      • A description of the class.
      • A summary of the methods defined by the class.
      • A summary of the instance variables defined by the class.
      • A summary of the class (static) variables defined by the class.
      • A detailed description of each method defined by the class.
      • A detailed description of each instance variable defined by the class.
      • A detailed description of each class (static) variable defined by the class.

      Project Documentation

      The Trees page contains the module and class hierarchies:

      • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
      • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

      The Index page contains indices of terms and identifiers:

      • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
      • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

      The Table of Contents

      The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

      Project
      Contents
      ...
      API
      Documentation
      Frame


      Module
      Contents
       
      ...
       

      The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

      The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

      The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

      The Navigation Bar

      A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

      Label Highlighted when... Links to...
      [Parent] (never highlighted) the parent of the current package
      [Package] viewing a package the package containing the current object
      [Module] viewing a module the module containing the current object
      [Class] viewing a class the class containing the current object
      [Trees] viewing the trees page the trees page
      [Index] viewing the index page the index page
      [Help] viewing the help page the help page

      The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

      A timestamp below the bottom navigation bar indicates when each page was last updated.

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Bird-class.html0000644000175000017500000001372610750103050025205 0ustar pronovicpronovic inh_example.Bird
      Module inh_example :: Class Bird
      [hide private]
      [frames] | no frames]

      Class Bird

      source code

      Animal --+
               |
              Bird
      

      Instance Methods [hide private]
       
      fly(self, dest)
      Fly to the given destination.
      source code

      Inherited from Animal: eat, sleep

      epydoc-3.0.1+dfsg/doc/examples/listed/frames.html0000644000175000017500000000110610750103050022174 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/listed/redirect.html0000644000175000017500000000225010750103050022521 0ustar pronovicpronovicEpydoc Redirect Page

      Epydoc Auto-redirect page

      When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

       

      epydoc-3.0.1+dfsg/doc/examples/listed/index.html0000644000175000017500000000110610750103050022026 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Mammal-class.html0000644000175000017500000001417210750103050025525 0ustar pronovicpronovic inh_example.Mammal
      Module inh_example :: Class Mammal
      [hide private]
      [frames] | no frames]

      Class Mammal

      source code

      Animal --+
               |
              Mammal
      
      Known Subclasses:

      Instance Methods [hide private]
       
      run(self, dest)
      Run to the given destination.
      source code

      Inherited from Animal: eat, sleep

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Fish-class.html0000644000175000017500000001373210750103050025213 0ustar pronovicpronovic inh_example.Fish
      Module inh_example :: Class Fish
      [hide private]
      [frames] | no frames]

      Class Fish

      source code

      Animal --+
               |
              Fish
      

      Instance Methods [hide private]
       
      swim(self, dest)
      Swim to the given destination.
      source code

      Inherited from Animal: eat, sleep

      epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Animal-class.html0000644000175000017500000001501110750103050025513 0ustar pronovicpronovic inh_example.Animal
      Module inh_example :: Class Animal
      [hide private]
      [frames] | no frames]

      Class Animal

      source code

      Known Subclasses:

      Instance Methods [hide private]
       
      eat(self, food)
      Consume the given food object.
      source code
       
      sleep(self, time)
      Sleep for the given period of time.
      source code
      epydoc-3.0.1+dfsg/doc/examples/listed/crarr.png0000644000175000017500000000052410750103050021653 0ustar pronovicpronovic‰PNG  IHDR e¢E,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIMEÖ)Ó}Ö pHYsÂÂnÐu>gAMA± üaEPLTEÿÿÿÍð×ÏÀ€f4sW áÛЊrD`@bCÜÕÈéäÜ–X{`,¯Ÿ€lN‡o@õóðª™xdEðí螊dÐÆ´”~TÖwÅvtRNS@æØfMIDATxÚc`@¼ì¼0&+š—Šˆ°»(’ˆ€ ;; /ðEXùØ‘?Ð n ƒª†— b;'ª+˜˜YÐ#œ(r<£"IEND®B`‚epydoc-3.0.1+dfsg/doc/examples/listed/inh_example.Primate-class.html0000644000175000017500000001615510750103050025725 0ustar pronovicpronovic inh_example.Primate
      Module inh_example :: Class Primate
      [hide private]
      [frames] | no frames]

      Class Primate

      source code

      Animal --+    
               |    
          Mammal --+
                   |
                  Primate
      
      Known Subclasses:

      Instance Methods [hide private]
       
      climb(self, tree)
      Climb up the given tree.
      source code
       
      grab(self, object)
      Grab hold of the given object.
      source code

      Inherited from Mammal: run

      Inherited from Animal: eat, sleep

      epydoc-3.0.1+dfsg/doc/examples/sre-module.html0000644000175000017500000012474510750103050021526 0ustar pronovicpronovic sre
      Module sre
      [hide private]
      [frames] | no frames]

      Module sre

      source code

      Support for regular expressions (RE).
      
      This module provides regular expression matching operations similar to
      those found in Perl.  It supports both 8-bit and Unicode strings; both
      the pattern and the strings being processed can contain null bytes and
      characters outside the US ASCII range.
      
      Regular expressions can contain both special and ordinary characters.
      Most ordinary characters, like "A", "a", or "0", are the simplest
      regular expressions; they simply match themselves.  You can
      concatenate ordinary characters, so last matches the string 'last'.
      
      The special characters are:
          "."      Matches any character except a newline.
          "^"      Matches the start of the string.
          "$"      Matches the end of the string.
          "*"      Matches 0 or more (greedy) repetitions of the preceding RE.
                   Greedy means that it will match as many repetitions as possible.
          "+"      Matches 1 or more (greedy) repetitions of the preceding RE.
          "?"      Matches 0 or 1 (greedy) of the preceding RE.
          *?,+?,?? Non-greedy versions of the previous three special characters.
          {m,n}    Matches from m to n repetitions of the preceding RE.
          {m,n}?   Non-greedy version of the above.
          "\\"      Either escapes special characters or signals a special sequence.
          []       Indicates a set of characters.
                   A "^" as the first character indicates a complementing set.
          "|"      A|B, creates an RE that will match either A or B.
          (...)    Matches the RE inside the parentheses.
                   The contents can be retrieved or matched later in the string.
          (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below).
          (?:...)  Non-grouping version of regular parentheses.
          (?P<name>...) The substring matched by the group is accessible by name.
          (?P=name)     Matches the text matched earlier by the group named name.
          (?#...)  A comment; ignored.
          (?=...)  Matches if ... matches next, but doesn't consume the string.
          (?!...)  Matches if ... doesn't match next.
      
      The special sequences consist of "\\" and a character from the list
      below.  If the ordinary character is not on the list, then the
      resulting RE will match the second character.
          \number  Matches the contents of the group of the same number.
          \A       Matches only at the start of the string.
          \Z       Matches only at the end of the string.
          \b       Matches the empty string, but only at the start or end of a word.
          \B       Matches the empty string, but not at the start or end of a word.
          \d       Matches any decimal digit; equivalent to the set [0-9].
          \D       Matches any non-digit character; equivalent to the set [^0-9].
          \s       Matches any whitespace character; equivalent to [ \t\n\r\f\v].
          \S       Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v].
          \w       Matches any alphanumeric character; equivalent to [a-zA-Z0-9_].
                   With LOCALE, it will match the set [0-9_] plus characters defined
                   as letters for the current locale.
          \W       Matches the complement of \w.
          \\       Matches a literal backslash.
      
      This module exports the following functions:
          match    Match a regular expression pattern to the beginning of a string.
          search   Search a string for the presence of a pattern.
          sub      Substitute occurrences of a pattern found in a string.
          subn     Same as sub, but also return the number of substitutions made.
          split    Split a string by the occurrences of a pattern.
          findall  Find all occurrences of a pattern in a string.
          compile  Compile a pattern into a RegexObject.
          purge    Clear the regular expression cache.
          escape   Backslash all non-alphanumerics in a string.
      
      Some of the functions in this module takes flags as optional parameters:
          I  IGNORECASE  Perform case-insensitive matching.
          L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale.
          M  MULTILINE   "^" matches the beginning of lines as well as the string.
                         "$" matches the end of lines as well as the string.
          S  DOTALL      "." matches any character at all, including the newline.
          X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
          U  UNICODE     Make \w, \W, \b, \B, dependent on the Unicode locale.
      
      This module also defines an exception 'error'.
      
      

      Version: 2.2.1

      Classes [hide private]
        error
        Scanner
      Functions [hide private]
       
      match(pattern, string, flags=0)
      Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.
      source code
       
      search(pattern, string, flags=0)
      Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.
      source code
       
      sub(pattern, repl, string, count=0)
      Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl.
      source code
       
      subn(pattern, repl, string, count=0)
      Return a 2-tuple containing (new_string, number).
      source code
       
      split(pattern, string, maxsplit=0)
      Split the source string by the occurrences of the pattern, returning a list containing the resulting substrings.
      source code
       
      findall(pattern, string, flags=0)
      Return a list of all non-overlapping matches in the string.
      source code
       
      finditer(pattern, string, flags=0)
      Return an iterator over all non-overlapping matches in the string.
      source code
       
      compile(pattern, flags=0)
      Compile a regular expression pattern, returning a pattern object.
      source code
       
      purge()
      Clear the regular expression cache
      source code
       
      template(pattern, flags=0)
      Compile a template pattern, returning a pattern object
      source code
       
      escape(pattern)
      Escape all non-alphanumeric characters in pattern.
      source code
       
      _compile(*key) source code
       
      _compile_repl(*key) source code
       
      _expand(pattern, match, template) source code
       
      _subx(pattern, template) source code
       
      _pickle(p) source code
      Variables [hide private]
        IGNORECASE = 2
        I = 2
        LOCALE = 4
        L = 4
        UNICODE = 32
        U = 32
        MULTILINE = 8
        M = 8
        DOTALL = 16
        S = 16
        VERBOSE = 64
        X = 64
        TEMPLATE = 1
        T = 1
        DEBUG = 128
        _cache = {(<type 'str'>, '#.*', 0): re.compile(r'#.*'), (<type...
        _cache_repl = {('#\\1\\3\\2', re.compile(r'#(..)(..)(..)')): (...
        _MAXCACHE = 100
      Function Details [hide private]

      sub(pattern, repl, string, count=0)

      source code 
      Return the string obtained by replacing the leftmost
      non-overlapping occurrences of the pattern in string by the
      replacement repl.  repl can be either a string or a callable;
      if a callable, it's passed the match object and must return
      a replacement string to be used.
      
      

      subn(pattern, repl, string, count=0)

      source code 
      Return a 2-tuple containing (new_string, number).
      new_string is the string obtained by replacing the leftmost
      non-overlapping occurrences of the pattern in the source
      string by the replacement repl.  number is the number of
      substitutions that were made. repl can be either a string or a
      callable; if a callable, it's passed the match object and must
      return a replacement string to be used.
      
      

      findall(pattern, string, flags=0)

      source code 
      Return a list of all non-overlapping matches in the string.
      
      If one or more groups are present in the pattern, return a
      list of groups; this will be a list of tuples if the pattern
      has more than one group.
      
      Empty matches are included in the result.
      
      

      finditer(pattern, string, flags=0)

      source code 
      Return an iterator over all non-overlapping matches in the
      string.  For each match, the iterator returns a match object.
      
      Empty matches are included in the result.
      
      

      Variables Details [hide private]

      _cache

      Value:
      {(<type 'str'>, '#.*', 0): re.compile(r'#.*'),
       (<type 'str'>, '( +|\\n)', 0): re.compile(r'( +|\n)'),
       (<type 'str'>, '(^>>>.*)\\n?', 8): re.compile(r'(?m)(^>>>.*)\n?'),
       (<type 'str'>, '<a[^>]*\\shref', 0): re.compile(r'<a[^>]*\shref'),
       (<type 'str'>, '["\'](.+-div)[\'"]', 0): re.compile(r'["\'](.+-div)[\\
      '"]'),
       (<type 'str'>, '[^a-zA-Z0-9]', 0): re.compile(r'[^a-zA-Z0-9]'),
       (<type 'str'>, '\\$([^\\$]+)\\$', 0): re.compile(r'\$([^\$]+)\$'),
      ...
      

      _cache_repl

      Value:
      {('#\\1\\3\\2', re.compile(r'#(..)(..)(..)')): ([(1, 1),
                                                       (2, 3),
                                                       (3, 2)],
                                                      ['#',
                                                       None,
                                                       None,
                                                       None]),
       ('#\\2\\2\\2', re.compile(r'#(..)(..)(..)')): ([(1, 2), (2, 2), (3, 2\
      ...
      

      epydoc-3.0.1+dfsg/doc/examples/epytext_example-pysrc.html0000644000175000017500000002405510750103050024016 0ustar pronovicpronovic epytext_example
      Module epytext_example
      [hide private]
      [frames] | no frames]

      Source Code for Module epytext_example

       1  # 
       2  # epytext_example.py 
       3  # 
       4  # Example code used by the epytext manual. 
       5  # 
       6  # These functions are used by epytextintro.html to illustrate epytext, 
       7  # and show what output is generated by epydoc for a simple docstring. 
       8  # 
       9  """ 
      10  Examples for the epytext manual. 
      11  """ 
      12  __docformat__='epytext' 
      13   
      
      14 -def x_intercept(m, b):
      15 """ 16 Return the x intercept of the line M{y=m*x+b}. The X{x intercept} 17 of a line is the point at which it crosses the x axis (M{y=0}). 18 19 This function can be used in conjuction with L{z_transform} to 20 find an arbitrary function's zeros. 21 22 @type m: number 23 @param m: The slope of the line. 24 @type b: number 25 @param b: The y intercept of the line. The X{y intercept} of a 26 line is the point at which it crosses the y axis (M{x=0}). 27 @rtype: number 28 @return: the x intercept of the line M{y=m*x+b}. 29 """ 30 return -b/m
      31
      32 -def z_transform(f):
      33 """ 34 This is just an example; there is no z_transform function. 35 """ 36 return f(12)
      37

      epydoc-3.0.1+dfsg/doc/examples/sre.Scanner-class.html0000644000175000017500000001426110750103050022725 0ustar pronovicpronovic sre.Scanner
      Module sre :: Class Scanner
      [hide private]
      [frames] | no frames]

      Class Scanner

      source code

      Instance Methods [hide private]
       
      __init__(self, lexicon, flags=0) source code
       
      scan(self, string) source code
      epydoc-3.0.1+dfsg/doc/examples/crarr.png0000644000175000017500000000052410750103050020367 0ustar pronovicpronovic‰PNG  IHDR e¢E,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIMEÖ)Ó}Ö pHYsÂÂnÐu>gAMA± üaEPLTEÿÿÿÍð×ÏÀ€f4sW áÛЊrD`@bCÜÕÈéäÜ–X{`,¯Ÿ€lN‡o@õóðª™xdEðí螊dÐÆ´”~TÖwÅvtRNS@æØfMIDATxÚc`@¼ì¼0&+š—Šˆ°»(’ˆ€ ;; /ðEXùØ‘?Ð n ƒª†— b;'ª+˜˜YÐ#œ(r<£"IEND®B`‚epydoc-3.0.1+dfsg/doc/examples/term-index.html0000644000175000017500000001144210750103050021513 0ustar pronovicpronovic Term Definition Index
       
      [hide private]
      [frames] | no frames]
      [ Identifiers | Term Definitions ]

      Term Definition Index

      [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

      X



      epydoc-3.0.1+dfsg/doc/using.html0000644000175000017500000004754110750103050016757 0ustar pronovicpronovic Using Epydoc

      Using Epydoc

      Epydoc provides two user interfaces:

      Epydoc can also be accessed programmatically; see epydoc's API documentation for more information.

      The Command Line Interface

      The epydoc script extracts API documentation for a set of python objects, and writes it using a selected output format. Objects can be named using dotted names, module filenames, or package directory names. (On Windows, this script is named epydoc.py.)

      Command Line Usage (Abbreviated)

      epydoc [--html|--pdf] [-o DIR] [--parse-only|--introspect-only] [-v|-q]
             [--name NAME] [--url URL] [--docformat NAME] [--graph GRAPHTYPE]
             [--inheritance STYLE] [--config FILE] OBJECTS...
      
      OBJECTS...
      A list of the Python objects that should be documented. Objects can be specified using dotted names (such as "os.path"), module filenames (such as "epydoc/epytext.py"), or package directory names (such as "epydoc/"). Packages are expanded to include all sub-modules and sub-packages.
      --html
      Generate HTML output. (default)
      --pdf
      Generate Adobe Acrobat (PDF) output, using LaTeX.
      -o DIR, --output DIR, --target DIR
      The output directory.
      --parse-only, --introspect-only
      By default, epydoc will gather information about each Python object using two methods: parsing the object's source code; and importing the object and directly introspecting it. Epydoc combines the information obtained from these two methods to provide more complete and accurate documentation. However, if you wish, you can tell epydoc to use only one or the other of these methods. For example, if you are running epydoc on untrusted code, you should use the --parse-only option.
      -v, -q
      Increase (-v) or decrease (-q) the verbosity of the output. These options may be repeated to further increase or decrease verbosity. Docstring markup warnings are supressed unless -v is used at least once.
      --name NAME
      The documented project's name.
      --url URL
      The documented project's URL.
      --docformat NAME
      The markup language that should be used by default to process modules' docstrings. This is only used for modules that do not define the special __docformat__ variable; it is recommended that you explicitly specify __docformat__ in all your modules.
      --graph GRAPHTYPE
      Include graphs of type GRAPHTYPE in the generated output. Graphs are generated using the Graphviz dot executable. If this executable is not on the path, then use --dotpath to specify its location. This option may be repeated to include multiple graph types in the output. To include all graphs, use --graph all. To see an example of each graph type, click on it:
      • classtree: Displays each class's base classes and subclasses.
      • callgraph: Displays the callers and callees of each function or method. These graphs are based on profiling information, which must be specified using the --pstate option.
      • umlclass: Displays each class's base classes and subclasses, using UML style. Methods and attributes are listed in the classes where they are defined. If type information is available about attributes (via the @type field), then those types are displayed as separate classes, and the attributes are displayed as associations.
      --inheritance STYLE
      The format that should be used to display inherited methods, variables, and properties. Currently, three styles are supported. To see an example of each style, click on it:
      • grouped: Inherited objects are gathered into groups, based on which class they are inherited from.
      • listed: Inherited objects are listed in a short list at the end of the summary table.
      • included: Inherited objects are mixed in with non-inherited objects.
      --config FILE
      Read the given configuration file, which can contain both options and Python object names. This option may be used multiple times, if you wish to use multiple configuration files. See Configuration Files for more information.

      For a complete description of the command line usage for epydoc, see the epydoc(1) man page

      Examples

      The following command will generate HTML documentation for the sys module, and write it to the directory sys_docs:

      [epydoc]$ epydoc --html sys -o sys_docs 
      

      The following commands are used to produce the API documentation for epydoc itself. The first command writes html output to the directory html/api, using epydoc as the project name and http://epydoc.sourcforge.net as the project URL. The white CSS style is used; inheritance is displayed using the listed style; and all graphs are included in the output. The second command writes pdf output to the file api.pdf in the directory latex/api, using Epydoc as the project name.

      [epydoc]$ epydoc -v -o html/api --name epydoc --css white \
                       --url http://epydoc.sourceforge.net \
                       --inheritance listed --graph all src/epydoc
      [epydoc]$ epydoc -v -o latex/api --pdf --name "Epydoc" src/epydoc
      

      Configuration Files

      Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following is a simple example of a configuration file.

      Example Configuration File

      [epydoc] # Epydoc section marker (required by ConfigParser)
      
      # Information about the project.
      name: My Cool Project
      url: http://cool.project/
      
      # The list of modules to document.  Modules can be named using
      # dotted names, module filenames, or package directory names.
      # This option may be repeated.
      modules: sys, os.path, re
      modules: my/project/driver.py
      
      # Write html output to the directory "apidocs"
      output: html
      target: apidocs/
      
      # Include all automatically generated graphs.  These graphs are
      # generated using Graphviz dot.
      graph: all
      dotpath: /usr/local/bin/dot
      

      A more complete example, including all of the supported options, is also available.

      The Graphical Interface

      Epydoc also includes a graphical interface, for systems where command line interfaces are not convenient (such as Windows). The graphical interface can be invoked with the epydocgui command, or with epydoc.pyw in the Scripts subdirectory of the Python installation directory under Windows. Currently, the graphical interface can only generate HTML output.

      Use the "Add" box to specify what objects you wish to document. Objects can be specified using dotted names (such as "os.path"), module filenames (such as "epydoc/epytext.py"), or package directory names (such as "epydoc/"). Packages are expanded to include all sub-modules and sub-packages. Once you have added all of the modules that you wish to document, press the "Start" button. Epydoc's progress will be displayed on the progress bar.

      To customize the output, click on the "Options" arrow at the bottom of the window. This opens the options pane, which contains fields corresponding to each command line option.

      The epydoc graphical interface can save and load "project files", which record the set of modules and the options that you have selected. Select "File→Save" to save the current modules and options to a project file; and "File→Open" to open a previously saved project file. (These project files do not currently use the same format as the configuration files used by the command line interface.)

      For more information, see the epydocgui(1) man page.

      Documentation Completeness Checks

      The epydoc script can be used to check the completeness of the reference documentation. In particular, it will check that every module, class, method, and function has a description; that every parameter has a description and a type; and that every variable has a type. If the "-p" option is used, then these checks are run on both public and private objects; otherwise, the checks are only run on public objects.

      epydoc --check [-p] MODULES...
      
      MODULES...
      A list of the modules that should be checked. Modules may be specified using either filenames (such as "epydoc/epytext.py") or module names (such as "os.path"). The filename for a package is its "__init__.py" file.
      -p
      Run documentation completeness checks on private objects.

      For each object that fails a check, epydoc will print a warning. For example, some of the warnings generated when checking the completeness of the documentation for epydoc's private objects are:

      epydoc.html.HTML_Doc._dom_link_to_html........No docs
      epydoc.html.HTML_Doc._module..................No type
      epydoc.html.HTML_Doc._link_to_html.link.......No descr
      epydoc.html.HTML_Doc._author.return...........No type
      epydoc.html.HTML_Doc._author.authors..........No descr, No type
      epydoc.html.HTML_Doc._author.container........No descr, No type
      epydoc.html.HTML_Doc._base_tree.uid...........No descr, No type
      epydoc.html.HTML_Doc._base_tree.width.........No descr, No type
      epydoc.html.HTML_Doc._base_tree.postfix.......No descr, No type
      

      If you'd like more fine-grained control over what gets checked, or you would like to check other fields (such as the author or version), then you should use the DocChecker class directly.

      HTML Files

      Every Python module and class is documented in its own file. Index files, tree files, a help file, and a frames-based table of contents are also created. The following list describes each of the files generated by epydoc:

      • index.html The standard entry point for the documentation. Normally, index.html is a copy of the frames file (frames.html). But if the --no-frames option is used, then index.html is a copy of the API documentation home page, which is normally the documentation page for the top-level package or module (or the trees page if there is no top-level package or module).
      • module-module.html The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      • class-class.html The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType.
      • module-pysrc.html A page with the module colourized source code, with links back to the objects main documentation pages. The creation of the colourized source pages can be controlled using the options --show-sourcecode and --no-sourcecode.
      • module-tree.html The documented module hierarchy.
      • class-tree.html The documented classes hierarchy.
      • identifier-index.html The index of all the identifiers found in the documented items.
      • term-index.html The index of all the term definition found in the docstrings. Term definitions are created using the Indexed Term markup.
      • bug-index.html The index of all the known bug in the documented sources. Bugs are marked using the @bug tag.
      • todo-index.html The index of all the to-do items in the documented sources. They are marked using the @todo tag.
      • help.html The help page for the project. This page explains how to use and navigate the webpage produced by epydoc.
      • epydoc-log.html A page with the log of the epydoc execution. It is available clicking on the timestamp below each page, if the documentation was created using the --include-log option. The page also contains the list of the options enabled when the documentation was created.
      • api-objects.txt A text file containing each available item and the URL where it is documented. Each item dotted name takes a file line and it is separated by the URL by a tab charecter. Such file can be used to create documents linkig to the API: see the --external-api documentation for details.
      • redirect.html A page containing Javascript code that redirect the browser to the documentation page indicated by the accessed fragment. For example opening the page redirect.html#epydoc.apidoc.DottedName the browser will be redirected to the page epydoc.apidoc.DottedName-class.html.
      • frames.html The main frames file. Two frames on the left side of the window contain a table of contents, and the main frame on the right side of the window contains API documentation pages.
      • toc.html The top-level table of contents page. This page is displayed in the upper-left frame of frames.html, and provides links to the toc-everything.html and toc-module-module.html pages.
      • toc-everything.html The table of contents for the entire project. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the project.
      • toc-module-module.html The table of contents for a module. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      • epydoc.css The CSS stylesheet used to display all HTML pages.

      CSS Stylesheets

      Epydoc creates a CSS stylesheet (epydoc.css) when it builds the API documentation for a project. You can specify which stylesheet should be used using the --css command-line option. If you do not specify a stylesheet, and one is already present, epydoc will use that stylesheet; otherwise, it will use the default stylesheet. For a list of the CSS classes used by epydoc, see the default stylesheet.

      Errors

      For a description of the errors that can be generated by epydoc, see the epydoc(1) man page.

      epydoc-3.0.1+dfsg/doc/index.thumbnail.png0000644000175000017500000001442210750103047020541 0ustar pronovicpronovic‰PNG  IHDRiP••Ì,tEXtCreation TimeWed 23 Aug 2006 18:00:43 -0500ã±;5tIMEÖ 9K[Vx pHYsttÞfxgAMA± üaiIDATxÚí\Ys#×u¾·±5bH‚û¾Íp†³k¤‘Dz%Û’#Y‘SöKòGò”‡¼%•<9©<8GU.YÑb[ÒŒdk4‡³pßI ‰µÆ¾Ü|àŒF Í=QR¥S,T£Ù¸çô¹ßwν§ÁÿõW¿:{îûNžRÖVVõ½½½­~ÿj0'Žº"]beqô‡ 3ë¾m ¾%ém50¦ÇQ>Ÿ_ŽûŠº±±900`0è… ‡™L¦å‹%û«ÓmÃç7¦ßo:k¶yçF³Íe`½V6{‹U*¬½›)160Î$éÛ6뛤\fWße'žcù,S“¬wˆ Ìdf3Ÿ³þ1fµ1˜¾¾È†&èüæ 3˜·­Ì²Éód)DT˜]²šïjbµZK¥ÒÕ«WeÙ„Ï»ÝîS§¦p¾R.ÝûðŸ WþÍh¶ïÌ^5ZœóçÿêokŸ n²µ68Îf®±·þš Œ}Û¾yɦكäÄÅ»ÌÒÂÊ%öú/ØÖ ‹î³x˜%¢tÍíO™ÍIo'Î 3tA±Èd™9<ìÇé~åãÇ''ïmË•#&g¢ÈŠ•£¿¬c¶/=ÏÖè¾ý‘pù:ÿì÷Ÿ3&£{d}«×û²·é¯sþÛöÇ3?¾Oº\@)–HÐüÅOW‘y‰óÿóøô¿.{{J>0 ÉhÌ[­ÌhdÅr^§cv;ëì¬àÅÇñî;©É¯½].³ZxÏé+·–Ò'F;¢[ëÅ’‰žW±XDÜ}ç»zyíµÎB׎9ïwXñB±ü£Ká\ˆv¼øn_UÕ½½½‹/>:ƒ×éééË—/›ÍæÚÉ›7ož;w.N/--:uêÛ6ó™ÈȈë±wtÜßå9|Ù—¾ûôÓO‘ D"‘O>ùÄãñÀÙlÖf³étºX,†Á•¿üå/ß{ï½·ß~{ttTQ”;wîàƒ—.]9òKÌÌÌ1uò$ûàvö,ÛØ`~?[X`““À`65Å2f³±\ޏ©0eppÃææØ‹/²ÍMÖÑÁVVè ¦¥…•J,•ÂT¢Ï——i´ùy6:J¯žª˜kÈ?ê[[ ÓÌ ;}šáËâuu•!62™L øº¯ýärà»îîî\.×ÞÞîõzVñxp¸±±155U.—q|üøñÕÕÕW_}µR©ììì 9Nøº­­íë†F QB”ϳtš¼ãpÐ+ Ã<ÒÞÎ’IV(ïཞÞÖ ‡éúÝ]Ö×GokþÅñÚÛËnß&‡b¼Å¿Z[ézœg»»é¸Æ‰µkðáèh”骅,Ë(šÐß]¸p¡î€CLO;x塌=]þ†ûPÂdœ3:;É*LwX«(w°ÿ‚×M5Û0 WâS8†÷1>k±0U%ÇÁ 1œÁ7B”uu±Xì 0kQŒÜéï§·ÃÃÀÊC ñßʧæ}G¹ñå—^zôþæüºå!º=;I¤T§­åYkyvжrI­çÙŒjöû\ÕôåJ©,ŠY×ò"Guù%±¶Šù-ÀmH73i^*#ZE$Â6yR4£¨XiÅ…y½à]Ý¢\æn·ÀøÉ1)±¯_ô?}FãqvØwÐ!0â³õäÚçîP¥Œ$fïsYæ°3×la=‹˜X6ÃÛýM9ŽU+ÿ_H€Ôáh‘ì Y_ã˜×ñ8¹/ŸÃKƒZ¾ôÝ;ï¼óÆo´Ø’L3 #ä’Tj÷ç-@­¥­mÇju}vÕzýomåRÒé²KüñKDá!‡4,œW¼Þ€ÍcBЉmpŒ90(¬-BI¤dsã3úà{]¿~}qq±z¸û‡oŒ Ê©$ëé“~úzØÒÓ«¹ï2™;I¥´¾ö–Rp‡½ðbøùK6͵”J…löF6ëHÄ_¶;ØöÏf)Ö–¹Ë…Œ¿ð¢ÜpquÀa°:c>ŸïO÷–mÖgŽâÑ„âq:žµ–g§(“Í8xîÀåðZí ˜µeK®ë_Hoþ¼rû&ïèÅ"—Íbe‰ë ÄôýƒÂíÖ@}1ã^Z€ /ÿ¸²´@`wõix¤b4Q21~¬Y¤« †Í$<@·Ýëè"dsy€,#tøÀ€zj]Q`e:W®{»<•0`þœ} åòÌëa²™À»`Z$•$wnKplƒûöv1…yw0ˆ@ˆ®Žªïfîðr…ÁG Tøn/Í\œIÄ9˜4Ò°Ô¯AÉæ„Ų‰qïÍp%ÉZÛ„É”öúŠˆµÎ.á°3­’?»cÃãQ2i®0ɬ"Øý»d ¸5­²H˜)‰DóZÀëjOOæÚŸ¥bÑÇû6ÑîýÄðŽè(Q¼>îôúH(x×fûÅô-rÒ±I•.}/ëri1Q¿"K‰Dqkó/æ( ÚÚ©Z¸yCZ[᧸~½þfÜR£9)—‹zýB"Pß_YæðŽNöþ»¼ÅF 8‚/¿óxÁÄúºâ;®xù W<’lÊÆòî[7øÏÞª<¸ÏQo2€qmm¢³KSõŠüƒ©ú“×*s³ÄŸ~"Œ ƒAx}ìØq͸"ö ÄÂû@ªg=^ @GæxæœÐ=ýNéÑ\‹q%ÊûDR¡Ú¿¿ƒVP›ÁÔ#eî×éÉ6Œ tWôö `9ÈÊf£=NΛWBãà»Þ>±½É-VJ€zðÍN¼'š¸G‡¸BŽ™L‹É$Ÿ™–²î‹„3NgÁÑ,òԋźäñDñ÷§Ãýoif3ò!â "€)%³q@ñØ„÷ŒÆ¹žÞÔ§W¤\Ž!1ÞXO8]¬o@x¼ÌßAŒ Ëa®H¤’ó²Ü{ÿž¹TâÇ'E"QòwæœNWCã­˜L;™Ì†¯ À¼ò±48(òŠz„îÙÆºÕ.‚¼ñƒ—§«Aí•J±ÅTÄ‹k«Ü×ÊFÇ=½ÚÂw\шÍ©„­œq£¢WìŠs@’ÛCKªWžÕU.*ì§oT>» ôa¥"eàªÊFG…Vð.¼C\!W¥5®ÖV‘NÓŠ^Fvî‚v\]ÝåHƒßÀrÔÌ0¡n¶hé8ÈüÏA…;Z›,Eñô”]î»]=þÔ=q¼RÈs¹lÿ€íášh†Ìë}Ç¥”šZ1‡g€+ØØ’•òó— v‡±¢]ä †<.’J…²YÿÚ*»;CÅ,ê³Ý]ޏøá+jEh3i+•’Ù‹EÓ:ýE$­Çã©¶ö¯zváü(®X±·|Çß ™lÚÎã]ÄVH¹¦oñ7ߪ ¯4à$ª‹ã'´Ä;ä¾û;îuâŠ7þ²råcŽLÉÞÀ y62JÉ—VŠnýÙƒÙšNsÄõùç´±"ŠŒó0W œXÜæ>­m%âìöM (û¨·ECYZàµÍÖP äúûûHÅYZe¨j´Ò’ެ!Oµ5¡ÞwnÏ¾Ž­šLg‘Ð#/yùG•@@›ÉÚ*îê¾g³9UµU·G Þ4šè‡ÝZEÅ]©Å:Ý?ЕÏù F¶¾Æ¶6y_?-FÃÜëÛ÷x}šù®TVʺ^767'WÊlhX¨jaêt9Wв۬P*–*ñp$üÅ5¿ÅÌÒÊ! yžÉ°Auô˜=§Qùœ/„”X[˶]¨RÓ¡p^]­ºGœU«½4,–ˆÃ\q}n½ÅbÃÐ:‡kÕ²&•ù#‰Ä^—³Ö¾[×¢ŒYöxÂ…kpAíõÑÛ'ÿJ5E‡ÇiRRiÕZN×Ç](`±[íwnó×VÞííÄb6!YÑÐwùBq}ÉH…1 ¥ë×È µ6¸"GÅ ¥¯H˜ßüyåýw%„ ܉p§C”+Ôô$_)›+.>°ãƒù<;sV,Îñ“§DóKß•r 1\ï;5Åæîr ÝÚGM¾½Eu…¤cºŽde™×–€VWøæ&‡³L&àÜ*V¥2ݹÅ®(ÈÂø^ˆ³$‰Nêžì+Ák(Àà(ò¶· ì&Ži໚Ôû®Ý¿k6ΛÍÏgTÒçï¨lo©S§èoo OÛÎ…¹<µÛÐNs,ºúLë‘÷÷ׇØ6ûr^¿áñt¥U¿^ÏFÇÄâ"w»S’¹é ûzߥ³j$’¤øÂ¼ÉWo?ÒýìðxEÛÑL.—Î&5¾²æ_Xb-CŽŽ¥ò¥§HËŸ„OÒÙl6—ZZÞØXw"Æ‹èèÌXl¢Ôå ù0WÜZÜrÚµö?DÍ54›1:‰¦L •jsø¯Y¦“O+áXÜçv«Æ?þqœi`´oT¤ùÈJ*i*$íÏMûeó™sâw¿•übxT,Îr§‹mnp`PÉ×J«»ÅÚŠž:%¬O)“iöžùp+>ÿqE,Æ[[…V©ÿ‘ÓÌ-*Ì¡èüqgš@™¿Ó%šéÉ—š³û{Lªð…9:¾Ç¢dÞn¨Ú¬Y¸ù9ÞÖF=²,”/4º^´¶Â1æ„Ã<@8xcê´0j 5®(—Qó‰¥%sÛ<©ˆ z0§Ù›Tﻞ¾ ¹;6q¥L{‚îÉ”òx%«Õª™AU¿a·;B¡£QŒŽ1‡340Ø®­ F\Qœ( àŠÞ•::Åè¸lQ¸TS¼µMÀ`ž­,qT»ÇOÃÓ§/zîÖuC$ÌkëN(ry>8$Ÿ¾%éÎt×þd@¥l0ŠÓgÅÝ;È«ÉÔK½½¢ábIW­ìêíŽF¸ÿ{À£j N&‰(áäÒ÷¶RûŽa|6+[*Ý P!ðô½¾†ò‹iÕaõ¸`’Ò*!´XùÚ qE(Hz3J¼š,–ê}×ÕˆìÞt8_AyÔÛÇ,Va±Ûý>/ùõÒ7pÍn·w&`ÇËΞ< -àŠÑ±Ïü÷îˆÚýÔq08,*Õg<¶·‚Ý=+­÷’Î(™ìõ[»¡-ØÙZØÔi…4^¼‹&”T6¯¨»‹‹~„B /¡½R¤$“Ù¼ºÚÚqn õàÁ½(K$¸IžK,(­îÏòÝÈàðù©óȰ`R6S}î&ï*¤ibª*=üЍõ¦Ô²°vƒVêO¥Ø©ÔKj’ÎÚ€’;“Fs'G‡ñzþ í’ŽÞŸôè?{Nüþ}é…+HS@¦J€'“H‰iEa¢Õ'‘NÖpÿgWy­ó’sfw$…*ÞáÔd·i³ê…ñ?ùI8ÝsÅÛ¿‘âÁ¢ïÿ@ƒÁïm3IWÀAÓ·%¬Êè0,¸C„ ¬E^‚L=a â†G"´ÆA,ɉÄA !%òµ‚š´!\ ¾vµÇ…¯® ÔB.·6ƒ^ƒÚÞÛù|lâµ|úÀG¢­oÿê…ͪïèø u…¢L††·;´íîûÒw…þ+Gg>?ÌÁ]&x<Æ:µ÷]:—/2~íFhsé>ØæOéÍR:¯e]®(TØ^,¾¼G¾íñ§¥HìYø.žTóe±ŒE£±tšKœòyœÞmNÝÑ\140è8q±}j’vF0ƒ WÙœã»ÀäÍçhÙÃh¢“®îÕƒ+”i±XNKµ\Æ™Z£ß£ƒæåÄèУîZ8Q6Ów4W¬®pçgÏ‹?|(]º\QSt£‚ºÔÞ.æfia %¾D)Á«ÌÕàä½òO¦ˆ+úûÅÖ&¯•G€§a9rˆWZi~_%Ð?” »ÝâÂEñ›W°Rµ›ÞŸíÍ-±_Q«+`Ì[D²ÄŒ¼P Øí‚¸ÂFÛ.á0ïê¢%Æ$•:àŠZ¢›z‘Žê…–ZKôH¬W‹}ÚH„¶·ñmÁà:¨ õ¨ÞÓ«õ”×·ܺb¶¼‰œóʜήîžÇ.‡÷JŸÝ¾µq:§4åìù:-Ú¸¢³ë#Gǽ™ñ”JA½· ¯Q½4{›}ý+­÷]¾T6Zl³‹»‘¸N€+ÄøD¾Id=,Qª"L 5IÄÒJSPfh®O©BgØ §cÉXr2-Äà½9š^ A³=/ÛQz4W ôõÛ,§1}¸Ã!ôÔôë²ZhÂ"½D€4\HÔ ¸w|œê$‡ƒÉ&'œˆ =M×ñNŒW\zžŽ5hÁD®‚¦uÅÊ27JÄ‹ó´M‘ËR_=° …Dÿµª5ÿzæ=ÃrÕg²"!2™Èq:‰éMbw—iø r±p°å†¼é(Âî 6àæ³îÇU3bJœæ)ì’å*Wô4«¨> p»×“ÊK@SZ ‡ ºÈçSS§Â/ýh^+«¬-ºÙÚ&PUÁ¹pe­/üŸÿAº~­¸»j^K¹œ÷z?ììz¤3šˆ"¬-Âb-?i³ùvðú¸+ îôµÝ› éõr*Çò!ÚsøÒ©/h‡åà S‹#[*Ï.ÆgÈ‚ègN ,W&/ Çó¾ÎRó졨ƒÕVÅd6¶$¤ËçY¦Pv·55øÑ\Ñ×Ók3»,ßcs³ÜéµDTÕYÊòv¯Ðj]ˆU¹"e£ƒÔåW“ÚWMö÷ Ë5éYšÄ륋_9Y(xÒÕ¦‘Æäh®X^䲞¸†ÝÆ<>š¹˜MªÊµÝLøà= 3³)¤Ë%€tÉäÁî¯ % lV (è½ßI:pE” ŽˆðímƒÇéwiÆE“ *õwpƒû®À ÊdøÊÇ+B [ýIÍ1Åé,Bîêst0•Îsâ\M6„1œ•ËÒ®H:EA[ ·gk«Ù–ÂzßÙí«¡à¿ŒŒ•∠€k[[üØñªK_ãÝ¥GˆN÷¾¿ã3¤DðZ(H=îs¯~ø¥"„¯uÇéÒ`ï\aµþN¯¿-Ù\mGTÜ¿'Á®Ñ±Õ&¯Ÿ³ÈÂÆŽÝœ+ic®Ìõ%QÒ®¼!§iÒ®pµR’í댦²Âhå#ÇiÅ’¢"±Í>0Xˆ*)IJ7©HIg\mPd lG‹‚%"…¹³\Äü½¬aº8š+z:»[d"ࡺÜߣå§hÑ´®€¾ó[ª+¢62&öw©\XŸ8&<^M¹¢–¦R]Q¤Ÿ"ØÜ eÈT z¹Âl¡… ²Ö\ŽŠ “L9Mw¸©í[ЯNùZéÇ ñätÑvR  5WX¬ËËKÿX*•àÁr™îLÿÀÊÅÄ+?ј+ …wlö߃ŽZZÄÍ/€  sÂåZÓPK±˜“¤ÿ,¾(—D2E à¢H˜ïíŠá­¹Bg”Ï_ºOÄl}™35ÏÊ\÷,Ö :û‡t:š‹‘¾že… ¥uƒã¢Ä$ Õ%3ÙîÁQÎ-Û[±Z[ˆN'˜ŽyýM):š+:ý]VÙe› Ÿ³éì¤6`IrECôœaCOq|­´{û÷÷˜÷ õžO>à Úá”ÜÚ*’unXá²Y‘r}¹ÎÞxA{À«+Ëç—;æ +i‹,ƒ€ægx*&Œ»¬æãL»'•¨…zá¶9ãµ§Löw(}E­Žä ²¶Š›»]RÁKƒÃ"õõ¡Æ¿ùijg©pC"•âå¿«W¶…¡=ÀIEND®B`‚epydoc-3.0.1+dfsg/doc/manual-othermarkup.html0000644000175000017500000006340710750103050021445 0ustar pronovicpronovic Alternate Markup Languages

      Alternate Markup Languages

      Epydoc's default markup language is epytext, a lightweight markup language that's easy to write and to understand. But if epytext is not powerful enough for you, or doesn't suit your needs, epydoc also supports three alternate markup languages:

      reStructuredText
      is an "easy-to-read, what-you-see-is-what-you-get plaintext markup syntax". It is more powerful than epytext (e.g., it includes markup for tables and footnotes); but it is also more complex, and sometimes harder to read.
      Javadoc
      is a documentation markup language that was developed for Java. It consists of HTML, augmented by a set of special tagged fields.
      Plaintext docstrings
      are rendered verbatim (preserving whitespace).

      To specify the markup language for a module, you should define a module-level string variable __docformat__, containing the name of the module's markup language. The name of the markup language may optionally be followed by a language code (such as en for English). Conventionally, the definition of the __docformat__ variable immediately follows the module's docstring:

      # widget.py
      """
      Graphical support for `gizmos` and `widgets`.
      """
      __docformat__ = "restructuredtext en"
      #[...]

      To change the default markup language from the command line, use the --docformat option. For example, the following command generates API documentation for the existing regular expression package re, which uses plaintext markup:

      [epydoc]$ epydoc --docformat plaintext re
      

      reStructuredText

      reStructuredText is a markup language that was developed in conjunction with Docutils. In order to parse reStructuredText docstrings, Docutils 0.3 or higher must be installed. If Docutils is not installed, then reStructuredText docstrings will be rendered as plaintext. Docutils can be downloaded from the Docutils SourceForge page.

      Default role

      Epydoc replaces the Docutils' default interpreted text role with the creation of documentation crossreference links. If you want to create a crossreference link to the somemod.Example class, you can put backquotes around your test, typing:

      `somemod.Example`
      

      Consolidated Fields

      In addition to the standard set of fields, the reStructruedText parser also supports consolidated fields, which combine the documentation for several objects into a single field. For example, a single :Parameters: field is often used to describe all of the parameters for a function or method:

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
          - `size`: The size of the fox (in meters)
          - `weight`: The weight of the fox (in stones)
          - `age`: The age of the fox (in years)
          """
          #[...]

      Epydoc will automatically extract information about each parameter from this list. These consolidated fields may be written using either a bulleted list or a definition list.

      • If a consolidated field is written as a bulleted list, then each list item must begin with the field's argument, marked as interpreted text, and followed by a colon or dash.
      • If a consolidated field is written as a definition list, then each definition item's term should contain the field's argument, (it is not mandatory for it being marked as interpreted text).

      The term classifier, if present, is used to specify the associated type. The following example shows the use of a definition list to define a consolidated field (note that docutils requires a space before and after the ':' used to mark classifiers).

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
            size
              The size of the fox (in meters)
            weight : float
              The weight of the fox (in stones)
            age : int
              The age of the fox (in years)
          """
          #[...]

      The following consolidated fields are currently supported by epydoc:

      Consolidated Field Tag Corresponding Base Field Tag
      :Parameters: :param:
      :Exceptions: :except:
      :Groups: :group:
      :Keywords: :keyword:
      :Variables: :var:
      :IVariables: :ivar:
      :CVariables: :cvar:
      :Types: :type:

      Graph directives

      The epydoc reStructuredText reader defines several custom directives, which can be used to automatically generate a variety of graphs. The following custom directives are currently defined:

      Directive Description
      .. classtree:: [classes...]
          :dir: up|down|left|right
      
      Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down).
      .. packagetree:: [modules...]
          :dir: up|down|left|right
          :style: uml|tree
      
      Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down). The style option specifies whether packages should be displayed in a tree, or using nested UML symbols.
      .. importgraph:: [modules...]
          :dir: up|down|left|right
      
      Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed. The dir option specifies the orientation for the graph (default=left).
      .. callgraph:: [functions...]
          :dir: up|down|left|right
      
      Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed. The dir option specifies the orientation for the graph (default=right).
      .. dotgraph:: [title...]
          :caption: text...
          graph...
      
      Display a custom Graphviz dot graph. The body of the directive (graph...) should contain the body of a dot graph. The optional title argument, if specified, is used as the title of the graph. The optional caption option can be used to provide a caption for the graph.

      Colorized snippets directive

      Using reStructuredText markup it is possible to specify Python snippets in a doctest block. SUch block will be colorized as in epytext Doctest Blocks.

      >>> def double(x):
      ...     return x * 2
      ...
      >>> print double(8)
      16

      Doctest block are mostly useful to be run as a part of automatized test suite using the doctest module. If the Python prompt gets in your way when you try to copy and paste and you are not interested in self-testing docstrings, the python directive will let you obtain a simple block of colorized text:

      Docstring Input Rendered Output
      .. python::
      
          def fib(n):
              """Print a Fibonacci series."""
              a, b = 0, 1
              while b < n:
                  print b,
                  a, b = b, a+b
      
      def fib(n):
          """Print a Fibonacci series."""
          a, b = 0, 1
          while b < n:
              print b,
              a, b = b, a+b

      Indexed Terms in reStructuredText

      Epydoc uses indexed terms to create a table of terms definitions. Indexed terms are created using the epytext markup X{...}.

      If you want to create indexed terms in reStructuredText modules, you can use the term interpreted text role. For example:

      Docstring Input Rendered Output
      def example():
          """
          An :term:`index term` is a term that
          should be included in the index.
          """
          #[...]

      An index term is a term that should be included in the index.

      Index
      index term example
      x intercept x_intercept
      y intercept x_intercept

      Javadoc

      Javadoc is a markup language developed by Sun Microsystems for documenting Java APIs. The epydoc implementation of Javadoc is based on the Javadoc 1.4.2 reference documentation. However, there are likely to be some minor incompatibilities between Sun's implementation and epydoc's. Known incompatibilities include:

      • Epydoc does not support the Javadoc block tag @serial.
      • Epydoc does not support the following Javadoc inline tags: {@docroot}, {@inheritdoc}, {@value}.
      • Epydoc adds many field tags that Sun does not include, such as @var, @type, and @group.

      Javadoc Fields

      For compatibility with Javadoc, every @see field is assumed to contain a single crossreference link, unless its body is quoted, or it starts with an HTML tag. See the Javadoc reference manual for more information about how the @see field is encoded in Javadoc.

      Because Javadoc does not mark end of the optional argument, field arguments must contain exactly one word. Thus, multi-word arguments are not available in Javadoc. In particular, all group names must be single words.

      epydoc-3.0.1+dfsg/doc/home.thumbnail.png0000644000175000017500000002052710750103047020365 0ustar pronovicpronovic‰PNG  IHDRjP~¢w ,tEXtCreation TimeWed 23 Aug 2006 17:42:51 -0500+Ø\tIMEÖ -Q‚ pHYsttÞfxgAMA± üa ®IDATxÚÝœYp×ÕÇoÏ>Úw ˆ$6³™ÍÄ@À.'&õ}NpU*qRIUЇ|UyH’¼ä1yHž’ªÄUÙ*UvÀƱcc¼`›Å2 ±jA Ú—‘4Ò¨§§¿ßí3†ÑH ¡€Ã)©«ûöíÛ÷üïYï½=Æá×ßX°h¡ºg²íX{_l0lŒFU¦?êuÏž=ûÞÿo§˜mîvELö»®z.Z¸¼ªj ÏÇ,û¦ÕßÐéÏÎÏϵKƒóçÏØL=8²,sèšq£¡)¿t®×ñL£ ÓâÏõççdKÉ­öö®îî‡ÍÚ–lÛ^åÈÙðh4¦ÔÀPÈc«8|¯½öZffæž={Nž<ÉåŽ;¤üÌ™3óæÍ»qãFFFÆš5k(‰D".Ã=oNiÄV>wDª]kî>Ô¬›î¾y‰cá¼)ï.õ«YAÕßk·6¨ÊµÆD]liPåóQÕTgsâñië@ÜmoQ¥å÷ J( 3¼^C__ŸËå²,Ë0Œììì9æååõôôDBõ++íXL¼îE æDb*42ßàà`NNί~õ«k×®=ùä“ÇŽ{á…^~ùeìÍy½ÞÆÆÆwß}÷Ô©SÛ¶m}ê÷G‡£Ñ¨òeÙ©¼Õ¼ïñgÖžü{ÁœÊî¦K…sW/XS¼à1¹››o\©V³‡•2T~‘êéP»Ÿ»Qsúø¸]^¡nÔ¨…UÊëµÝÕߣv~ãvZðt#³æªw©ç÷§Gy:{öìÈÈÐ Áxaa!Ì %YYYõõ .—dÁ`°©© »T___QQ‚áφr¹Ìˆ‰³}ž1ø€Ìï÷/^¼ø}>%EEE{÷ÊÊÊëׯ/Z´ˆ:Ï?ÿ¼Ûíjò´SáÑHnP?nFF†:ë8É+™ÃÑï[ã dz\UÁÜb¯ÇÅ­Oùüºf€úUPÏz$Ý.ÕÝv›ù@@Í©PL{þR#3ÓÎÈR1Ûðùìä:E¥ú¸l•5‘»¯‹ãÔ$.7C…º; ÀûÜ®‘œl8tk°7–ð€iNа¬ [#=å%YF4Ôu«Û«ú¾¨å5 W̶‡GÇà›;wîø×¬[·NN€5þâÜ\\ÇÙ‡—ä¸3üjtP—W”æîÏ-_¾Ü-ºÕÖÆHŽoíc0ÖÎÃ&B…ãK››š‚Ù…y™‰’ÑѨÏç‘“ŽŽ6=\޾y½jØÂ:ð¡žÈð½¼ûˆl—ä(Ïãñx±§ÍÎsׯ]ò¾öÊ+«W¯>~ü8¢êv»À–-[8€ ÓþÍ›7KJJ¶mÛöì³Ï>løÒÓ…Ú¦¨kÝ.c특g/Þì ÏŸS8Žtt,íY66üƒ#:p4|°ŠX¥´52¢hS !}ã_¼qãFÔ|É’%×®]KÉáÇqD”˜¦‡‘_|æuÊšöiùâ9¾Œ<9ZVå¢2ŸÏ-—+–”EGBrŽÐù=F̰#׿ý­Ú¹×£LSå䨶6 ¤š3—¢ UI‰*.žìÅX_•¤ãÐO~ò9Ù´iÓÆeBúÃ>^°`KV–fÓãÇò†«§.©êYsJs[Ú3ƒ8÷ðˆéõ¸û;›ª– ƒvÌŠÙ–rc¶‰Áçç«áaUV¦A¤¹7”߯ˆçpA*.ÎUׯ«Œ í`󢔫£»Ï²bhqo(‰Dñ–AŸ?Á#Ѩ5¯pÈp{QÙ¦¨¡á‹D´| a‡†TA>O$#ŒÏ]‰€·råJ¹¼råJyyyÖÝžŒÅb555‰§0}ë[)§¡c¬Å &LC‘¸üLÃ1ýž.¿[Ç[±BÝá7:4kÖ,ÂF"L@iooßµk×ðððÕ«W¹Ä‰ôÑG?ýéOßxã––‚ƒ¹577×ÖÖQ.]º”ñܽ{÷CÁqÚ¤áçH´ÁñèÑ£¸K ôÔÍx:þüðÃï}ï{ ¨9ýãÿ¸oß>„Ž æa³?e2GGF#a/€òÖÖÔµ—.MuÆe<|¸šÞ^mC³³1®Ú q20 ëc’;:´ýG,Ó‡/¸àdá63SûÜ–UY©—ò òîáœþ.cÄTÙÓÉÙT}}ÜMKèƒïž5K»ìž…ÌÕÖê¸'á%ŠÃW]­C–… µéïW55jg8¶¯Õ·Ebž…sr‚~D6 •–ÆëHüÈ´e‹Fö‘$IèÔòåZõ øÄgpŒÄç¢Hé´2rLd &y‡Ë•›kÙ1)¾G56œœ4|€ÕܬÑ!lF…;;µRˆ9»|Y‰|QaÁ]Å´¬ÑüüÜQÛö¸¬û|ý;yÚûLÕ4R¾Tyܶßsº³K1ó¶áôºUñxÐÈŸ•±»GT¸5ºaÙí`¸¡¡÷a³ð0É »«k[¯5t¸{¡ˆ·wØÓöÄ \«?þçó÷ ¸/\i¿rs¨k ½íÇdꉆ‘ä‡8irˆ"ÊñÏ^ºt)m›òÈx"®"„L4>%ß½yóf]]œ‡B!éíý“njھ`FÌmGé–¥"–U™^åv{=dpq2"Qe»\¾Ì€³Ç·bšæÁƒüñÏ>û¬²²’\‚ø±´´”!oÞ¼¹‹ Ô{ï½G×ûúúÚÚÚ``ïÞ½ï¼ó¹ ™ À­ßq1<ÒÕÕµgÏêZWSN>3{öìîîn—ËvŒw‰ÉoݺE†CtI7"‘Á¿a<Å[ÈsrrvìØA(ü—á–••1ôpÆ „Ÿ<>gÎ:–ŸŸoY-Æë©·;±h1!|–eæfE•¡ìQ”7bÆ‚Ùyݶ²ãHqfEÍ¢¢|ÓVÞtö®žzê)ÞúØcÑ] -ËÌÌ ƒ‚H±CÜ¢— ¡9çpK}ž¢÷<¦V«W¯ÎÈȢѨ4¢´ßrÉ$›ß!TÚ‚ûÉ¥}.á8h™r†!;”H>ÎëV­ZE¹^|pÞ‚¼¬M &&‡¯Àß³0¯+q]0&pƒ}ú/AåI¹ÂÞÁ†í@Ì [»v-Çp8<~¶I3ØBÔ_¼x1w“]H%Œ©À'%°—6}”[ÊÉmžyæ™ärŽtƒñU-))Á ³²öÀQj~õ«_Mi#] ŒÅ?뙀¯|öì)-Ô’u4uÆú‡ÆÂf£]ÆúÛßþ†°ðzÆœ“eË–8qbÅŠ ð°páB4èƒ>(,,Dè¸F(ò /¼pìØ±O>ùni¤½½!að‘/$õîtèk_ûÚ‘#GÊ7žE¸Ðhxûþ÷¿ÿÅ_ôöö^¸p—"57nÜ@Üh6QUÞÎÐ1d@±ò:ùôÓOéºÌiœÊô–Ê HûO?ýô_þò— ¥Ec:I[M£õù¥†@vÑœ™³L>88ˆ¶¶¶¢• |ð@'Pj”HäŽ#l$t¹¦¦Ω‰\tÖÒœ#´¢P\R¶Á»^‡†iD$ËYˆˆ[ê#G\Šv#ã ňrL~t m•¡âu mÒgYÀÊÈléX>’´¹î¸6^Ãë.ï`…×c‰Až‰w& õ” Îñç? v C¨oΨĨÏSà‚‹À™àÐhØãœ ˜|Y$Ñ€%Äì0–xæRô@ÌŸ¬ Èš$ØÕZZZÄAW®\¡}nQ œiNēމ³âte’†øl3.‰J[¶l $™üÀ™3g(=8¡VÅÜ6æ ]Qy<äПÿüg -|þùçô ¶Q%TÔèðÁÃ'Ê«@‰—8|ø0=fxé+O-_¾…Å<ÉSÊñKÝÃ/16¸c ¿ûÝïVWW3ßùÎw^}õUqÊ ,@èĉÓáM›6]¾|™[@ñâÅŠŠ ÞXUUE7Ž· žÀôÒK/Éú }CýÑ_T_Œð¾ñÆœ0<ßþö·½·ã;•wYeå¯ýkø¤r„×#àÀ4 t`yùÝï~Ç0¢¼õmÖÀˆ‹ø&'0š¥:îgË Cô¬|F(q ‘eXB¦ÝþŒSšö—¿üe¢¨!zÉû¦„÷ßìä2¢ƒVƒøo4ßåA„ yM³ÐåÒS5W®èékŸOO´´´“G_b´‘ Æ\ˆø!^t€‘ Æœ¨yD:GjrÄi VÒŠø(Ç8bžb±YD8ÊÉ8‰ÄñÛh¹æùó2=@i^|ñE|+bA;;wîDèp¸£5úŒX$ÆžôôôHhÅI4—ú“ éþ¿ÿ¸ °™c$K´fáÐ ¹¥—Ù#}A´(Ë.É5F†ÃXœFwwÙÍ›øDYOð ê¨1/O56êu»¼¼ÎÜÜÌãÇ#Ý`”è,f‘¨¼PCÌ%bˆ¡@öQOŽèýƒs¸â4QUÆpi¡¹y6)9CÕÞN„¯Z[5|ŒÖÑ£º¨äèhB j°&¸€* Œ¢´‰S¢y¯Þ»ãr¡d(Äa¸#¢¥øb¡ér{tBqQ^ ïJÎ\´v¶¹¶¶x8W¦jR¦§ÏââþÅ‹S7™£}‘8ú-AÖD¡V¢(1ë¡¶éYYdËvÌH¤cݺ»Ï/¦¼hòo2åMkÓRÚerÊå ûýÍ 2•——OŽ)@`Î:;k±Ë` ŽÄ«H¨!(/>!Õã¡@¹¨€ªÒ9ÚA@p¯ÀŠÇ8"žTCôx$¹|ëV® Sƒ A|G䮪jíÁƒ¸—Eâyh³3êýÙºu+²‚Ñ Yz‚;Bi‚è!nTÆX¡”ËÑ£Gà}ûö!nãŸNà’V*ß{0€§£ô5±yáÂ…Ñ?x€^J¤"Á—(¯ØAÊ%Ö#H¡Ô¿Ï Å]œ5º‰“(OÒµ³JÚ” 5/‰­oæ]ÀÇQÚá–„4‚má„q ãˆQzâ‰'$ùIKZyË)À9üð‡?ĵ#JXY A%|£­Â±éЉ–ŠxqIÒ||ÊeJ&”¢)‰ÊØoÄVrX)™\¡IÛ´IÌâ½;÷Tå‰DNž< vtñCû‹_ü7H/å$L…“Î&3JÄzè ÃM3àÒ(ˆè)åÓ ‹  Œ<"I7ß|“AFgÑJä‚ TfÌè oÇ2bäqã’ÆQ(*ß'v„ÊÓ&OÀïÿ‡äšèo­ Yà cp+*†Òᬕcæ%%ÁQ ýŽîÞ½{'Îr=™ê@9‚Má7oÞÌ0HÊŠ¤Ý÷à)îy[{‡Â‘Œ ÏŒZí]‹ç.#è÷¶w¸ÇÖÖ9°h^¡Ëí*ÎϘÒ:ï#Fir^¬\íõ¶« =ýáÑQ+48r­±ÓŽÙ=}áÏÔutÞlíí¦0fÅêšñ-àS"m2‘¸EE§ô,£{Þ,d „õRÛã«+Ÿ×S¥DVÚzzâ+m$ ÄÛãWÚ††@¹ï>ßúÈP\y È´††ôr-¹*Á޲|Þ×§7®QhYjÒPáRò47™l¿C‰ΓŒdAGŽçÎKnŠÂ”5ăRžR?AÄ^RSޏrRìÄÊQJ›xsb@©œR'ÑÕ‰––âËä@&s¦¤\ˆ!áº~ªíÛ5ލ-9¬{çfOŸÄŸ‰4†˜ŽwËô¯dD9d§NºvíñÑ2a&ù,<à»I3pµ$B„ÔL}{÷î=xð ±! Sí?ø!¹=…ÄCo¿ý6¯ `ðŒðã|ðL “_KLN›Ä<²Â¡8mܸ‘à‰·3Ÿ:‰f1ÐâþýûeÿT2iÏ»tyÕáÃúÝ,F‚Ü›À—ûñÇJf^D +*Ðnkþ¼ÉÒ¬‘r"ò‘ `ñ •áe$ V™‘—¸¤`’BîÊ´³Ç!Þ‚xR 3‚0ÊÜÕ(Ltƒ1~<"sÎyÌW£:gÏžE~^M`Ÿë°“2㢕ç°o_œ[¤ïÖ­Û{«ž~ZÛ;Lc#bØÞ®¦DÿøÇ?ªªªèLó¢ÅŒ3礫 @_Éüe Q儨Xf¹ÎóóóIHñþóŸÔ_¿~=¬¾ôÒKëÖ­CôxŠôfÓ¦M„ÖHŸ¼ |aàΜ9Ã8É‹¨ sæ/¿üò׿þõ#GŽp‹$ôežÜÉ(—•¯¥K—&Š´WÞW_Õ_"À`²1äwåJmOžÔZ,MáªUwWÞ™¢”¬yFH¦ð&º ÜÊùve’ÒLX‰ë@[±Œ‰ÜµÅc„Ãq/,tá‚ÆwþTò%L’¬× G%QFþ±ÇCmQ%ÌýEÃZãOP4Æ_f_¸%i)2Ee¤c¿jÕªÚÚZ„T–î8¢w’öÑ&JŠè½÷Þ{¼‹§dÂؓÉ÷O\ZŠo ÿÆ7â× ÕР‰ïŽqåE£Vݼ9µÀŒÌËË%j‚MÌlc˜e£¶Ÿ8VÜ%ZCð½p‚(5Š7@ñA™f¥«W¯nÛ¶ 9# @ °ÂÙêÎÐ>-0wiå]²¬ê¯ÕÒ‡"}DÈEEjýz-•o½¥Q“pÃ6?å#ÀJaôQJžÎµÄºèx?ñ5©f•Vy.ÄM¦¹QX`Âÿ"eœ—•éBà+-ÕªÝØ¨îyZ: á ÑM$K9_…J°ŠXÉÞYYç5”mœ#‰¢¨*’++èÜ=}ú´lÏ'ŠDB‘5qʲ߇š¸„eû€ßÀ&Ð8%²ZO!‚è8Š]»v‰OÃȲÔ])®¼3ã=A[´HcJh±d‰.¡‡Ka4ªœðhúDÿ>X´áBa1^0‚ðƒ—$Ô‚[’}C„5T xƒsÙa„j‡,lÉÔ!"){3¸²”vƒq’Y~DŒšõõõkÖ¬ÁÐud¶™èZÖ9™²¾ºCy\£V[«•wíZ®½òŠÞ·‹ôÑ RIaw·µ¢r”—N#‰YX ²ÄeB•d­’WP™ðE¦#'ZQJž|N«ŒÉÞüµ5…Ò+ï¦Mñ,ÔB¾þ#H&Š&î“íÝB&_Þ]¾|Yvÿ!A(æÇ¼Ü¡ .p‰zŠ8àd)AåE6‰ø8¢ìÈ#‚&û7ÀÊx Ù\ ʲ̀}”HŒ")F“»4"þ‡C®QˆéIzÊ;À#!cßÒ¢1"•À[r"+ß­­úœ¬nêÎ==¡•À{¨RX%PÀN%öô¡_ òO¥%L*-`*gÒ…|Ý)Îy–@‡sSÈ‘Ê/˜NÆRöa&÷-}Ø<þÄČ ®V¾MB×},mâ.Nž<¹sçNå„Á(цlô” W¨ÛW¾ò¼§ûu ¸Ú¾};ñ6>¸Iï°’_|ñ„¥C|Ð\$; {e° 2qÜ/â#¡øŠwß}ëÉ{‰ Q[ÎE<©@S¤}Ÿ|ò‰¸Çbæ´ ˆO>ùäøÕð ?LHL— ^(¯L—?ß•¥Óؼ-êÆ‰,×rùá‡åÊ•+e*!±LºaÃ|4½ç.ç„)pˆàÿ¢­H“ä²—[XY¥“KÌ(.›Ù¹"û6ê •tƒa 5§Í›7#€H7ç²^ Üã×§âÊ[]­7Ú I¼«®Në)ç(ì‰jÍ-˜â4œïË­¹å36'3ÙoʹlÁ] Ü&I^5Fš€5¡ÅŒõ“¿kGÙX*ÈÒÝ}Ò„9ï=N—êߌ¸ïŸÐGÆ“ÑF"°J ŸŽÄqŒ6ªºeËä …p½õÖ[ÜEXDÄd=vðB¿hUEr1y¨?î‚LD`9!Æ&f¤Qÿèý9k>%Ÿ<Èt) %)Ó¥2_O(nÛ÷õ¾aŒP‰eGäH ‘Í 87*G=aKD5Ò$kâ²… E[eû…´É]2.ƒ²p3³ð!qäMMjî\ýÝ}G‡¾Dà#®â.!R|“ϸ¤l®AHìÖ“šX+ü ¶ Ñ}ò9ƒ¨-±'4XYY‰JN(\²d‰L·V’òl‡@jü´JÊ„î Ã7³Ó¥p K ø`¡@U‘ àC‚p¨ÛÞ½{ zñ¼Ø8*£È2}‚û£ñ ƒ&å@F\ö§Ÿ~J9¢ô÷¿ÿ4qš@F}”Ñå;v<Èß:ù²L—&Úñe¦=]::tˆH±5™9uêþ‘¨‚ˆ$ÃüU9 -F+1jo¾ùæ®]»d¿šìðæòÙU$‹’xp‰;’e‚DKÀÌ]d<ñSØYÔ…»t†W ï2I#«N €°3ãMç|º4™èýŸþô§ýû÷K§;†¯|ÿý÷e‚dµ ¯B \QOÙÛŽÖƒÂsÏ=:2¯={çC8 ò¯RR`´»¶¶víÚµ²Ý—Ò>• }$ÄÁ á©?úè#PCëW¯^ Sú°{÷n¡=¥>Qæˆ÷®_¿žH …£/Ët)q ñ0®®®–ý£ÉwaQ•Ÿv{T__9¿ª«îti2¡ËÖ­[sº‚ ¡³ ²¬‘«Ê Dµ={öH}òSäN>z”… dP~7OÖŽe*—ErFÒ8Á½ ŒøÒžåAIuÓÒ$·RhÊÓ¥S3@2+‰Å!Í)Š#¡Œ° ‡è h¢Y@ (p.{’ÑDD#ñáá|‘4NÖ|AåMdY&«—ÍSŒÓgŸ}Æ ò….ßÿÈ”§KMs&“6 ¦ä­«0Lú‘vüA›…‰œ¼Mb£ÄjÑŒÓýN—:ÓnÃpéŸÏœ:%æ{8ðÌ3Ï9ra9~ü8…tÍ 8ÿýïÿì³ÏÊq)s|Ê™…VT•àQWWÇãø¤O&PÅ)#×T“mû¸¼Šìk™åomm•̱•hã dsx˜×1~wÝ %ŸÅ”–KtBÂα¥EO ࣠ñ²sƒBbi´,;dy:Ü7n¹ú‡¢A÷нÇôX"¼­|K { ƒcœ,Ø;w©¡ÁŠ|dž­ls’ßjBÁVRÒ[B ÐaH(Gm1y’ênß¾s+R‰ŠhY6oSN³È¸Ì÷Ñù6 ]–ýÅ`=ñnz»¦%ÐÔéº~ËÕÝukÊÓ¥¥¥Ö•ëì…:Ó±lAaÙt·9íü(† «\ xIà’+¬Ï%/c"wØ»IRŽä7&ŸKû)›ë'Z ±,ó“Zëó 5%åó½ÃuSž.T¦<Ëö£öè4€BÖ$Е9QÔýEIº._åËÞ*D¸\d=âƒd!§h7 xúôiT‰>qâò([ %F%º¬¬Œ6iG~X<òë¯¿Ž„â”0»òMuDg !yD×tŒ9IþÞ²=ó.0Ù#aå²b–Çcò‹™Á  º}}ff¦™m–•šr‹òP¿.ÌÉ1 Ãò{̼lO¶×Ì êé+jN㯭­Õ²¢õ½½=ƒƒEE>Ÿ›–™´õ‡K±ššK1+zþü¹‚‚|zUZZLÍÜÜœÚÚšœœlê÷ötgefð”aØ^¯;##Ø×ÛCi–c{û­ÌÌŒáá¡ÁÁP{{[OwW__oww§ËÀ.!¹õõu<›ŸŸQ‚àäçuvv„B}t#Óm†‡¥ÛQË ú"9¾o$3 Œw>¸P4{ùhTùwì²1iòˆ©êÑÕßÝjîp<¬¿qãÿ—# ËÑpIEND®B`‚epydoc-3.0.1+dfsg/doc/manual-install.html0000644000175000017500000002323010750103050020540 0ustar pronovicpronovic Installing Epydoc

      Installing Epydoc

      Downloading Epydoc

      Epydoc can be downloaded from the SourceForge download page. Epydoc is available in five formats:

      • RPM (.noarch.rpm)
      • Windows installer (.win32.exe)
      • Source install (.tar.gz)
      • Source install (.zip)
      • Source RPM (.src.rpm)

      If you are installing on RedHat, I recommend that you use the RPM file. If you are installing on Windows, I recommended that you use the windows installer. Otherwise, you should use one of the source install files.

      Getting Epydoc from Subversion

      If you wish to keep up on the latest developments, you can get the latest version of epydoc from the subversion repository:

      [/home/edloper]$ svn co https://epydoc.svn.sourceforge.net/svnroot/epydoc/trunk/epydoc epydoc
      [/home/edloper]$ ls epydoc
      Makefile  doc  man  sandbox  src
      

      This will create a directory named epydoc containing the latest version of epydoc. The epydoc package itself is in epydoc/src/epydoc (so adding epydoc/src to your PYTHONPATH will let you use it). You should periodically update your copy of the subversion repository, to make sure you have all the latest changes:

      [/home/edloper/epydoc]$ svn up
      

      You can browse the subversion repository here.

      Installing from the RPM File

      1. Download the RPM file to a directory of your choice.

      2. Use rpm to install the new package.

        [/tmp]$ su
        Password:
        [/tmp]# rpm -i epydoc-3.0.1.noarch.rpm
        
      3. Once epydoc is installed, you can delete the RPM file.

        [/tmp]# rm epydoc-3.0.1.rpm
        

      Installing from the Windows Installer

      1. Download and run epydoc-3.0.1.win32.exe.
      2. Follow the on-screen instructions. Epydoc will be installed in the epydoc subdirectory of your Python installation directory (typically C:\Python24\).
      3. The Windows installer creates two scripts in the Scripts subdirectory of your Python installation directory: epydoc.pyw opens the graphical user interface, and epydoc.py calls the command line interface. If you'd like, you can create shortcuts from these scripts to more convenient locations (such as your desktop or start menu).
      4. Once epydoc is installed, you can delete epydoc-3.0.1.win32.exe.

      Installing from the Source Distribution (using make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.

        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use make install in the eydoc-3.0.1/ directory to install epydoc.

        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# make install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        
      3. If you'd like to keep a local copy of the documentation, then use make installdocs. By default, this will install the documentation to /usr/share/doc/ and the man pages to /usr/share/man/. If you would prefer to install documentation to different directories (such as /usr/lib/doc), then edit the MAN and DOC variables at the top of Makefile before running make installdocs.

        [/tmp/epydoc-3.0.1]# make installdocs
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.

        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      Installing from the Source Distribution (without make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.

        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use the setup.py script in the eydoc-3.0.1/ directory to install epydoc.

        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# python setup.py install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]#
        
      3. If you'd like to keep a local copy of the documentation, then copy it to a permanant location, such as /usr/share/doc/. You may also want to copy the man pages to a permanant location, such as /usr/share/man/.

        [/tmp]# cp -r epydoc-3.0.1/doc/ /usr/share/doc/epydoc/
        [/tmp]# cp epydoc-3.0.1/man/* /usr/share/man/
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.

        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      Installing on Debian

      Epydoc 2.1 is available as a testing debian package (python-epydoc). The epydoc documentation is also available as a package (epydoc-doc).

      epydoc-3.0.1+dfsg/doc/epydoc_gui.png0000644000175000017500000001455610750103047017607 0ustar pronovicpronovic‰PNG  IHDRPiEÿçë+tEXtCreation TimeThu 6 Apr 2006 18:12:51 -0500Ó/â¢tIMEÖ\¥ pHYsttÞfxgAMA± üaÆIDATxÚí?ˆ%G~ÇKº Þ‚;°3pÆÑIhƒV0hÁÁ­¸À tƒ âp$œWÝ¡@ÈN¤±ÁFÉq—ج78$fבöÃNp‡&ØE«Èc`ha4ðè\ýjÔÓÛ]]]U]ý¯êóánÔ[¯ºªúÏ·ÕÕÝßzJqã矜œ]b!2X`…8þdó{òï•g´yyûë³3ñ´+±Zÿ•Ë«õ_RH!%’”§/m(õ}ùh¹Z ˆ‘År!V§Ë/==tK ?<@BlT“þ÷ã_Ú¯ÿg¯þÃЛ0<ªég•ÁŸÎOe²¼¥ŸmÌäÿrCÌäíýÆl¹3™}µ\nÌf+¡òôµ?!Zª'ñÁã½wþ#l-·Þý™¼“ ^lÎüñ|¶š­E!fb¹”Är&fK!52ËR*ªñÚ|>7g>YžlÎ6 ÚÜЦÏ_ùÉ+·þýVG{ gvŸßê´|©íãÇÇ{oîþñ°.ϵ?¿öá?xñïµÐNOO_ú‹—êV¹ÿ?÷Ÿ¨ec&WyîêsÕŸ$Ç_¿öêkÚŸ uÖpôG{½‡æ¡öoHÁ|üûG]þ³ïö³µ7þꊼL…«]rtt´³³£]kÃP"š‡YTÕ.{ûç3±XŠK2D>œß{ðÙ§æŸÉŸÔ??üÝÊ|óõÝ®>'³©{×·^ß½~õ¹kÏoÉ„Yöè¹LžAýSf“%Ë?Ÿkµ¹¸þòõ{¿¿W÷ëŸÜ¨ûI“ë"¿Ì¬~’oýÛ-¥í\íwîÞÙ|f³®"“àš‡þ¸ôêËÏV5_ìŠ_Èïó#õÏ¥Xä‚© Ï¢\wŸ×ĺ’žU6y]JÁWµä½wß«ûéäëƒ]É5¿÷7{üÓoÿýÛ*ݬvÑ(xæ¡n¾‘õº?ø;M,=|xtïÁ|gk¶óýí\äÞ>xë]©Ru™xõåkJŸû·ï­K».¾ Ú2¿Tò[oì>YÝõuÉYHW:W W…÷kVo¨:æ±:O1ÜÉ5Ÿ«ÝfE«çðJóí·Àƒûæ÷|öö¿Þ½ÿ ì*bïÿîž”«\ؾrYþݹ’ÉI*<øùŠ2åèñ‰¶duƒ ‹’% /®ÞѰBdl×.hŽð â¿9?x8/öçó¡»õZçOò¿3ƒ(gÈkÉ /ýZºÊ„ÅrL^1Û˜IÔrIÕr9×¼Ïsx§vxÓøýÕ½ƒG¿ýoý;jùÍyu8={tW±¯bÎиú€HmjŸê+Í›ŸÃŸÚ¬–b•]ÿ+ùgyüÕ©øf±øF,¾Yˆõ_¹\J9ÿ»’—ÍìïzÝõ”R¥(~û_‡uùóïãÇK!ÔÙ( grŸ).ªi½Êl¶©]e³^laÎSòÿ»oþf~6_œ\³õKX`!¢…ì‹=åxs.øÓ³Ó“Óc¡~XçcâYȾ¥Rðç÷ð—·vŽÜ)ËÇG³+;Y„ÿöÛo‡n ôžv©°ÿþþÅc¹ù—}¼6 ƒpëvöâ  !<@B x€„@ð àÁ$‚H¶Ûª7 :þâXý$Bµ©ZWÀÂRÆÍñ¦OáåuIýËÿ¡y€öøX\)´½œƒK´Xc¾\]èk×L÷ð¹äŠšì‡¼ Ðg¥“Ã-Âçrê!:uì6„¿‡c‰ØÁñ¿‡¯#l°U7ç Ú¡«çðJ¥ÝÞÕþˆš‚Ï;á ˜çåíü¸ð´Ãñ b”ãÕ=¼¶ ÝQ˜5t× ì-±ü /Ø@pøx !<@B x€„@ð àÁ$‚H/Þ¨7ï bÎ#üþûûC·:'ûx†·Y{x€„¸¸‡ßúÁÖЀ®Pß¿áâ'¤+‹ @dÀáÁ$„Éñ†Wq&ÊÞ{Úô‹«›¿¸9tËÀ™ºÁ¸fO;†ñ&„ì˜â4÷ð àÁ$‚H7Ák§ˆ´Ÿ7Òœ³ýü“Þ%t:õeÿ›P !|æ‡/ÎßZ AÅ–ò¿º/¦h§š5”SJ¬®’7Ïœ¿eÕÚMPUç™KËEUˬnæІ>?#‹'héln_NUÌŠ\ %yÔå×6̯êR±ÅœöEÕ …C@<_<}- râ–§¢ÂVíԌtð|ñ´ëî, Y£âÔ‡²"ؘ(>÷ðŠ®OYí¥$ïÇ&Çt[SdzK¯NY§W{h¼jäÁ0_°©ÔébäšÙ0Né„ÓãL§üu„´+u¹‹…R@Ö&Z–c½v¨¬.¿¹aU›7Ái5f¦G¡pëÒkïÞoéÍ9=Êqmacf¿ªí7Á\¾á×~†K xñ !<@B x€„@ð àÁ$„Õc9üª&A;u lLå^¼i¼xÀPXÎþL„HC > ç$_’Ø@„Hg 'F­e×ÊöEi›m™³e; ξôÂ΃±±oëÈÒBKÊR³Í9½«0ì ›Š`]zCÖFª€Ö‘mŠª¶Ê\Q5üZ~¥oó™}ãNh‰§/ý°îTu[WµÁ®ë¨÷ÙZ'|oy«Îö´"•v*ÃÖ‰'-¨ÚoæwLÿ.}éI˜kØ÷³Žôs ØlQÛ U„­  n‚7ôfµcÑÁ­#ƒUjv1§yŠMíþ´Ùi¡pîÒ{ žÕ ×yXG,ª±Lû-²l­eJcƒ¼éöꬰӠ;:<#O°Ó Sü§šÊ™h§tØæMt§ÁÔá]z€„@ð àÁ$­Âf¦N€Qút`¦Nº†mß½±[çxa6ÏÐfÀfÆ@ºÚDí»º†¾¶Àj~l6`$¤n€aéc¡Í`ÿò 60Ò5À°ÿ¾­ =`³ƒàáU$±‰Šbô1D{oÜ5öq»îÖÝfÿ7;òC]®†…÷ži_6Ðé`Ô•¯-Öiçh›ŠÍŒ¤ 0ìZ60r0À¹±ÚÞ 5‚F0üúÛƒ0þBG¤k€Ñö}é¡Ú3†VÁ€ðµ@B x€„@ð à ŸJýªs]Ëœ¿}{ A0À°¥ÿ‘m›OœH×£®IF%“ û}"UjvѨ6Ïãu`C]æƒ%] §M.R}ëÞ°O å¸R·‡ý®&NU@4¤k€¡=³ëšÚæCÔP!±‡ÐŠUFô¤k€¶.S Ôƒã#x§¯2‰ ±n`R1Ò5ÀO~Á®ýhÜu+êõÖ'ò8 Xe$Eºm(])ÂÞ²=-ËÁ*#n’6À0¯hÿOûv:aÞº°U8í(˜.`@ĘèðM;Fz´ØëÇo×…-Ÿƒ`ôM×»%Tß¾ŸÖBÏðµ@B x€„@ð à ŸJC`4–ÓÝvᙑ&`ØÂx5D`X6»®"­%F]k ©m:–1†Õ&ii€aß캊 ³Óº Æ£†%Fd`€1˜F›2ë*r­®± XbDaêÖ£XòàGÆ aÉVï·»ØÒtk|`€1˜†÷P‚÷³L×ýã]Œ 0|hc€aß캊‡3T9¥8ïwEÃ#20ÀÀþٮió—z4öËö ƒ©€ÆdÏ»q#ixСà× ËÌó‡uâ`€1%š[ø­Åa4|- !<@B x€„ò{xïñÞêŠ= 7~ákY‚Âð9j§» [PD}`T¿]/– ÊÌÿV×2\w°¬€F0À°Úä"- 0´»«ú²mõýyËÆcY0ÀÆ£Ÿoã…Å€¤À#L]Ã`X‚FƼI0ƒÆ`AöŒh} )0Àð¡†M™-Û†eÔFß656æÇ²üÀ# 8 À#~8ƒF

      k0+ßp¥púœ6©#Z0ÀFcá†Ñ Ì*À >1À(®¨~oé®YTÁc,~®®þætˆ 0Ò‚#’8 žÁ¡±Á 0"„#uðµ@B x€„@ð àbHÁ×½—æ±¢wQ~•úUgXË\`cu÷$Ä ¶ 8ÄÍè:„Œa 0 ¯îÛ”¦ýðÆÕ3Ã𱂆Õ& b€Q·»lšª}÷Þ¦=æ i¬"Œa 0Ú¸bx4Æï#,4âŒ0uù`Øå ž Œ0„Ú@{W ×öøyfT‹Mç˜F Ã`tÔKrõÌ(­ˆ…Fô`€áC{ŠºëK+FGíÑîC×c Œ¾ 0K°l’w{ÚlHc:Œ 0À Žé¤Áà˜N 0úf»…c+|- !<@B x€„ˆÄ££Š"#  Æ–‘`˜Û`¨HŠØ 0\Áã’"9Œ–͘4`$‘4À†h 0,àï­ôI´mŒ(ì+‘`˜ËÇã@1aŒîÞŸ£Ÿ±2aŒàNuý4`@¦m€ð |ŸÍ Áoý`kèÖ@+l»ô7qsè¦@[¬"üÞ{ó/çC7Ú‚@BŒâ{ø[·o Ý€ Ù™U S±²é†áΙô@Õþûû6ÙFáùÅ ´!}*CWö}d"<@B x€„ð7Àо‘fvzcÚRýÎbZ'¶s„¯zˤ†ò\›¢¢¿ãÖ…²˜héPg ¬¨z"›—‹k £}³+>®µ¥šh§uýhCÕRÙ©àdßìGÈA; ³ÿ,À$Pe×Ù1›?ÄÔFÍâ*%…‡e’®µÃRìlýÔZJÔ`ñJt‚×6ñ„%¿x)É Ù¥·qå)S4Y­¨6Ú7µ—OÁq˜†{x…ŸÿšŸ}³]zƒß«Ùhˆ{g4›œ–kT ¯Ö$‚H#ú~Š#7ñy1%ÂOÚl¢ÄÒCfZŒ"Â㊠cCžQZ05 >¾^ @²4 žÎ6@4˜OO 2Æ2h=€àÁ$‚H£xñÆ Þ h¤î­¡é ^ðj@uÔM‚ökó+¼  Ev q¤~ÿýý(ßdÖòì;7vN_º0UîþË{ö™›ß,Mí.µCo0J !œïáK¶Ø¥ùîœì5CM,9õ|zÃg2ÉqΕ;ÎVŒŠ0£ôÅI3ëf½­›O¶£É*l¦ï5d³\Ñ>‘NŒ·_£89†¨h»n&yQ3MEpÌÓ÷æ´¶\±»i}ºÀ9ÂÛL|cÖpG /E×Ò•Å,?­æWÌg3'Ûa/ζ¯Ýby¼õšm j o­ÃôÑZ™3—l]7È]¤†çð3ñ‡¥øƒìâ£$`'ã–΢³HŸÊ[£&‡.¾Ó²ý¿«™,%ûÇ‹3qíZc‰ÕOM î±ÞïÚÄ¢“¼ÓêhÍDÍD¢ÆCÙrʧÓÕF¤ê=tõš¼qÐN´1Ë–å…äׇâðp}Ûp§å^óóx·÷–Ç7z¦äæV7í‚yÊŸÓÕQ¤æWk×—Õ:—,wCvfYÿAVÿâav!ùqíwªõö¢²ñxo´»·©N[@KÚŸQuvïM§«›HÍ‚_¯¿Zž_Ed¡‡÷³ä?¿c«=íÜRÕí´4„t Ë6ŒëÓÕM¤Mþ¼Ã /Ÿž—b­§¹(´3[”ën„̻̦"€qbqºº‰´þ9ü»¿:¿x~*>ËJùÏ»®Ã’æÉ*<<Þ Ô]ÌØP 3ucxZüF‹lNW‘#|Þ7¤­i¤_b¾\Zp­ÀóùSc·?3=ª»ÀQ¤µå¶ÿêF@©÷úgÀ³ÎR¤ÅÇrµ^ö ü¶Ü@§óÀ/@1Ú'¸" éx3ˆêè¨CטOªÑ^´”»ôØÔD‰æM;Ô7¢ €„È"üŸrrztIˆÅ:Éga¶¹9»¼<=ò/Xh’X{~Oþ½òì6/o}v–Åû•X­ÿÊåÕú¯UÊÆ¥åÙñ3—·—ëBV$…R¬%Ö^§JýGóG˳¥æ!ÝJ˜Ë…X.¿xôÂîO½ !‘DëƒH,/$»‡—±^–²È>¯ËÂþbµN[©Î@%EæÙX§¬¥òO²¦²å+ŠJŠÌãZx²dQIÉ6Ú©=ŠÚ «çÑéÆÅ—'²¿È~ξ¿Ydk.M)ÙB¶JÞš¬»°Í+’B )攋Ÿ.$D§Ù Ý9=;=9=V?¯Ó­VYCvžÝýéº#çX`ÃBYb­tzá/_Ù9~ {/wUóöm!}ùøhve§e!¤“Nz]z‰©BþeŽT† IEND®B`‚epydoc-3.0.1+dfsg/doc/sflogo.png0000644000175000017500000000410010750103050016723 0ustar pronovicpronovic‰PNG  IHDRX쪷gAMA¯È7ŠétEXtSoftwareAdobe ImageReadyqÉe<ÎIDATxÚbTSRf ÄÄ7ïÞá¡ ®¬@L£iˆeºëÖa†·×Xÿ3È[1°±1ð«£éٳ眜‚‚‚dX@gΞ۴eË÷ï?3ÒR”ÄÅO¨fSãfðÈcà‡úðÁõ•ë·?{ùÂzUZJÒØÈHG[ È4êêµk@qNÎwïßeâ@0hÐìuuq¾yõê©“'5µ´\\]ÌÌÍ!âÄ,,(”›ŸGÿ€’’½xéÝÝÑææâÌÉÁññÉ+‰‹X5ä˜c*ØyàŠyD5ÔÕÏœ;'/'WU^ÊÉɹÿÀA ^e%E ÏgÌž}óÖíàÀ 216216>|ô(cnV&0t>þô|fZ*Ð ˆi*ÊJ@rÛÖ­.®®Ò22@ö”I“ˆ9]õíxÿþ}|l $Ò€IJJE€ ®\½(ncmŒ   „ ô<à•”M€1Œ% i?~üàààªJÙÈñïçã LÆÈAôÀËšÿÞ}cKÎÅ 8A!!? “À*V®^dܽw(´]YI (Q 46#5uÕ`0!t0™Zô¢°\°x Ð& û \ MÀP $P|Ó–­@[þüþã;$A ‚€A´¥€ èç鳿= Œ%`À¥€ÚN|ÿþ0%ß½w¨ˆ\]œ0½ ôûÆ«l®ö¸‘6Ø^ €„,ØŸ ÑÖÒD3 —h X  DŠšô9ÐÑ@×] ´œ9 æº:;/\¼ÄÖÆ9Œ1‹% v Æ3gÏBØA ÝÏ´ž#Ç?Ä5@[ Ü]{öÉ{÷î{?|Ãf¤‰+ €Þ" bˆçŽ‘—T‰'Mê&IPÚIÄ ¹ÀTt0þïÞ;Žp„?!©³ìAÀ„t"ГW¯]G x áoÃÈûð E ÞçÏŸ,Y8À¡ IÀL‡©h>Ðp[æ~`²ZÇ ˆ 9Ó `¢hïêZ&€¡Ì–À€€ä”ïß¿cUt ÁÓ6<˜˜YäE~»Ž3 üf1`º‚q÷ž½ðä ‡t PêÈÑ£ÚZZð” ktÂe8@1!g  R`1‰y B.Û®\½ Z\Ë O€ö­\³¨ -øá>ZDá¡!X áN°þµû .+®‚ÝJ_ÖÖx–Ç Ïe—€2‹¤f\Ɇ˜ €QÌl@4ÈØ½¡çÈÑcÀä tÐJˆ¯€ÁL>À´ƒl\xh0DH>r À²9X!™p)ž\7&!®_s'c:ôý»w vÇïð2 R¯£ÈLç *‘Q+@g 9]Æ(Â0ÅÁ 9*^Ooà1Ü\=‹[« .‚>| ‚[i’¦m’ÿ“„¡ËY£ª@ú´KÁ úäÁø³ª9 ,ô¿Q؈P@żw",n’½$¶ã4“e† ò´_ ‚tíûÙV)ìþi¨Žuéú!ÄÍPY}€7æx„ðõ6T„ŠEYä!Æ?¨=FöŸ5n„ˆÁŸgxu õ Rº ŒÿˆlbSÒé ÁÚ×5!jƒÊ²òÀà x³Ðê}îÙ½{ÝÚµ¸dhèÄÓ'O€Âöp)J}úô ™ LxŒ –!Nö ÈÉu-Xñj|bbUM5D P¤½¥õäÉ“ÒÒÒ7®_×ÐÔ¬ª©¹~ý<b£¢!  !ÈÝ €b–ÿ‡¨(-:ØÄÀ0+=ãÉãÇ'Oœð÷ñЬ]³(ûñãG 7&2 ¢Â*ªrâ@•@-˜ÆÅhˆe )ii ,í¦Î˜ìAÔ±w÷P…:Áõk×áñÌÇÇ”¦‘… 4 €qÖ¸¹›áÞñÿŸÿüSñf6B)ç Îú’#€äúuë€ä䉓ಟ?ƒÄ¯_»FÐ6€¬q|Ã—Ë ‚ÂŒný[rú×½|ÎbÊQ L,Ð! РÌï_2\߯ gÌ Å .ÉÌÿ÷ÛÌuÄë–‘dØ @ƒ1 þ¿yÅðéÃóË w70¼}ýï ÓŸ'߸AP£&xxf¸¼ Ð` ˆÌ|?o°1œ¹Ìplÿ¿Ë¯¾Þâÿý„™EAœç?ãÑ)8ׯ] ,2á‚À⣭¥^šÀË xchÀoñEŽ ÀÇÅWÝüñëÛ—«¼ßϰ³iò¸E³fÎüüéÐK¢¢¢ÀZèá•Ë—_¿~@JÊ ‘È_¿~•mÛºõçÏŸŒŒ ÀEQAaDT¤’²2PX¹\¼pÈØ°nÝ©“§\\]!6N™4 €i§ë×…GJ–ÿ Epydoc: Sample Configuration File

      Sample Configuration File

      Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following example configuration file demonstrates the various options that you can set. Lines beginning with "#" or ";" are treated as comments.

      [epydoc] # Epydoc section marker (required by ConfigParser)
      
      # modules
      #   The list of objects to document.  Objects can be named using
      #   dotted names, module filenames, or package directory names.
      #   Alases for this option include "objects" and "values".
      modules: sys, os.path, re
      
      # output
      #   The type of output that should be generated.  Should be one
      #   of: html, text, latex, dvi, ps, pdf.
      output: html
      
      # target
      #   The path to the output directory.  May be relative or absolute.
      target: html/
      
      # docformat
      #   The default markup language for docstrings, for modules that do
      #   not define __docformat__.  Defaults to epytext.
      docformat: epytext
      
      # css
      #   The CSS stylesheet for HTML output.  Can be the name of a builtin
      #   stylesheet, or the name of a file.
      css: white
      
      # name
      #   The documented project's name.
      name: Example
      
      # url
      #   The documented project's URL.
      url: http://some.project/
      
      # link
      #   HTML code for the project link in the navigation bar.  If left
      #   unspecified, the project link will be generated based on the
      #   project's name and URL.
      link: <a href="somewhere">My Cool Project</a>
      
      # top
      #   The "top" page for the documentation.  Can be a URL, the name
      #   of a module or class, or one of the special names "trees.html",
      #   "indices.html", or "help.html"
      top: os.path
      
      # help
      #   An alternative help file.  The named file should contain the
      #   body of an HTML file; navigation bars will be added to it.
      help: my_helpfile.html
      
      # frames
      #   Whether or not to include a frames-based table of contents.
      frames: yes
      
      # private
      #   Whether or not to inclue private variables.  (Even if included,
      #   private variables will be hidden by default.)
      private: yes
      
      # imports
      #   Whether or not to list each module's imports.
      imports: no
      
      # verbosity
      #   An integer indicating how verbose epydoc should be.  The default
      #   value is 0; negative values will supress warnings and errors;
      #   positive values will give more verbose output.
      verbosity: 0
      
      # parse
      #   Whether or not parsing should be used to examine objects.
      parse: yes
      
      # introspect
      #   Whether or not introspection should be used to examine objects.
      introspect: yes
      
      # graph
      #   The list of graph types that should be automatically included
      #   in the output.  Graphs are generated using the Graphviz "dot"
      #   executable.  Graph types include: "classtree", "callgraph",
      #   "umlclass".  Use "all" to include all graph types
      graph: all
      
      # dotpath
      #   The path to the Graphviz "dot" executable, used to generate
      #   graphs.
      dotpath: /usr/local/bin/dot
      
      # sourcecode
      #   Whether or not to include syntax highlighted source code in
      #   the output (HTML only).
      sourcecode: yes
      
      # pstat
      #   The name of one or more pstat files (generated by the profile
      #   or hotshot module).  These are used to generate call graphs.
      pstat: profile.out
      
      # separate-classes
      #   Whether each class should be listed in its own section when
      #   generating LaTeX or PDF output.
      separate-classes: no
      
      
      epydoc-3.0.1+dfsg/doc/faq.html0000644000175000017500000004602510750103047016403 0ustar pronovicpronovic Epydoc: Frequently Asked Questions

      Frequently Asked Questions

      Docstrings & Docstring Markup

      Q: Why does epydoc get confused when I include a backslash in a docstring?

      A Python docstring is a string, and is interpreted like any other string. In particular, Python interprets "\n" as a newline, "\t" as a tab, etc. If you want to include backslashes in your docstring (e.g. because you want to talk about file paths, regular expressions, or escaped characters), you should use a raw string. E.g.:

      >>> f(x):
      ...     r"""
      ...     Return true if x matches the regexp '\w+\s*\w+'.
      ...     """
          

      Q: Which markup language do you recommend?

      For many modules, epytext works well: it is very lightweight, so it won't get in the way; but it lets you mark important information about objects. If you would like to use a more expressive markup language, then we recommend using reStructuredText, which is easy to write, easy to read, and has support for a very wide array of constructs.

      Q: reStructuredText is capitalized weirdly; Javadoc has too much caffeine; and Epydoc just isn't cool enough. Will you add support for my favorite markup language xyz?

      No, but you can! See the documentation for the function register_markup_language(), which can be used to register new markup languages. If you add support for a new markup language, and believe that others might like to use it, please contribute it back to epydoc!

      Q: Is there a way to define a new field?

      You can add new fields that describe simple metadata using the @newfield field. See the documentation for fields for more information.

      Q: Why does epydoc render one of my epytext-formatted docstrings as plaintext?

      Since epytext is used as the default markup language for epydoc, it needs to be very conservative -- it will be used to display many docstrings that are not explicitly written using epytext, and it needs to display those docstrings in a readable way. Therefore, whenever epytext encounters a docstring that doesn't strictly conform to the epytext markup language, it renders it as plaintext.

      If you expect one of your docstrings to be processed using epytext, but it gets rendered as plaintext, then the docstring most likely contains one or more markup errors. Run epydoc with the -v option to see markup errors, and check for an error in the docstring in question. Once you fix the markup errors, the docstring will be processed as expected.

      Extracting Documentation

      Q: Why does epydoc use both introspection and parsing? Wouldn't one or the other be sufficient?

      Epydoc can extract documentation about objects from two different sources: inspection (importing the objects and examining them programmatically) and parsing(reading and extracting information from the objects' Python source code). Furthermore, epydoc can combine documentation information obtained from these two sources. This is important because each source has its own advantages and disadvantages with respect to the other. In particular:

      • Introspection gives epydoc an accurate picture of what modules will look like programmatically. In particular, some modules actively modify the namespace they define, or use various "magic" techniques to alter their public interface. Using introspection gives epydoc an accurate picture of what these modified interfaces look like.
      • If a module has dependencies that are not met on the current system, then it may not be possible to import and introspect it; but the parser can still examine its contents.
      • If importing a module has significant side effects, then introspecting it might not be desirable; but the parser can still examine its contents.
      • If a module is not trusted, then it might not be desirable to import it; but the parser can still examine its contents.
      • By parsing a module, we can find "pseudo-docstrings" and "docstring comments," which are unavailable via introspection. In particular, this makes it possible to associate API documentation with variables.
      • Introspection can give information about builtin and extension modules, which would be unavailable to a python source code parser. This includes builtin or extension bases for pure Python classes.
      • By parsing a module, we can easily determine which values were imported, and where they were imported from. This information is not available via introspection.

      Q: When should I use --parse-only?

      The --parse-only option instructs epydoc to only get documentation information from parsing (and not from introspection.) You should use this option if:

      • The project you are documenting contains untrusted source code.
      • The project you are documenting has dependencies which are not met (e.g., documenting windows-specific code on a non-windows machine).
      • You wish to document a module where importing the module would have undesired side effects.

      Q: How can I test whether my program is being documented by epydoc?

      Some programs or libraries need to take special actions when being documented by epydoc. E.g., you might want your code to skip certain set-up actions if it's just being imported to be documented. You can test whether epydoc is currently running by testing whether 'epydoc' is in sys.modules:

        >>> import sys.modules
        >>> if 'epydoc' in sys.modules:
        ...     print 'Epydoc is running'
      

      Q: I'm documenting a large project. How can I make epydoc go faster?

      Try the following options:

      −−no-sourcecode Don't generate pages containing source code with syntax highlighting.
      −−no−private Don't generate documentation for private objects.
      −−introspect−only or −−parse−only Extract information about objects using introspection or parsing (but not both). This may decrease the amount of information that epydoc can extract from your project.
      −−docformat=plaintext Format docstrings as plaintext, instead of epytext. (Docstrings will be rendered verbatim).

      Also, note that including graphs in the output can slow epydoc down significantly.

      Generated Output

      Q: How can I change the appearance of the HTML output?

      The CSS stylesheet can be used to modify the colors, fonts, and styles that are used by epydoc. You can specify your own CSS stylesheet using the --css option. (To generate the default stylesheet, simply run epydoc on a small module.)

      If your objections have to do with the actual layout of the pages, then I'd be happy to hear your suggestions for improving it; but I'm fairly happy with the layout, and probably won't make changes unless I agree that they improve the appearance significantly.

      Q: How can I change the appearance of the LaTeX, Postscript, or PDF output?

      Currently, the LaTeX output, and derived output formats, are not very customizable. If you have suggestions for improving the appearance of the generated output, please let me know.

      Q: How can I include graphs in the generated output?

      Epydoc can automatically generate a variety of graphs, including class tress, package trees, uml class graphs, and import graphs. These graphs can be included in one of two ways:

      Graph generation requires the Graphviz package. If the dot executable is not on the path, then its location should be specified using the --dotptah option.

      Q: How can I exclude a specific object from the generated documentation?

      Use the @undocumented field. See the documentation for fields for more information.

      Q: Why does epydoc add "-module" and "-class" to the names of the HTML pages it generates?

      There are two reasons. First, this ensures that the names of module and class pages do not conflict with the names of existing special pages. For example, if a module were named "index", then naming its documentation page "index.html" would interfere with the use of that name for the documentation's main page. Second, it is possible to define a package where a module and a class share the same name. In those cases, this naming scheme ensures that the two object's pages do not conflict.

      Q: Is there a way to link to the API documentation for objects using a simple URL based on the object's dotted name?

      Epydoc creates a page named "redirect.html" that uses javascript to automatically convert dotted names to the corresponding URLs. In particular, loading the page "redirect.html#dotted.name" will automatically redirect the user's browser to the URL for the object whose dotted name is dotted.name. For example, a link to <redirect.html#epydoc.cli.HELP_TOPICS> automatically redirects the browser to <epydoc.cli-module.html#HELP_TOPICS>. The redirect page can be used for any object documented by epydoc, including modules, classes, functions, varaibles, properties, etc.

      Q: Why are some values listed in the details section, but not others?

      By default, epydoc will only list a value in the details section if there's additional information beyond what's listed in the summary section. For example, if you define a function but don't give it a docstring, then all API information about that function can be shown in the summary table, so no details entry will be created for it. This helps keep the generated documentation consise, and the information density high. However if you prefer, the command-line option "--redundant-details" can be used to tell epydoc to display all values in the details lists, even if all info about them is already provided by the summary table. The corresponding config file option is redundant-details. This option was added in svn revision 1613, and is not yet available in the most recent release.

      Development of Epydoc

      Q: I've found a bug in epydoc! Where should I report it?

      Use the Sourceforge bug tracker to report bugs. If you want to hear back when we fix it, be sure to either log in to Sourceforge, or include your email address in the bug report.

      Q: I'd like to help! What can I do?

      If there are any features that you want to add to Epydoc, we'd be happy to accept patches. Patches should be submitted with the Sourceforge patch tracker (be sure to describe what your patch does!). If you plan to make several changes, we could also add you as a developer on Sourceforge. Email me if you're interested.

      For a list of additions that we'd like to make to Epydoc, see the todo list in the Epydoc reference documentation; or the SourceForge feature request tracker and bug tracker

      epydoc-3.0.1+dfsg/doc/epydoc-man.html0000644000175000017500000006034010750103047017664 0ustar pronovicpronovic Man page of EPYDOC

      epydoc (1)

      NAME

      epydoc - generate API documentation from Python docstrings

      SYNOPSIS

      epydoc [action] [options] names...

      DESCRIPTION

      epydoc generates API documentation for Python modules and packages, based on their docstrings. A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in ReStructuredText, Javadoc, and plaintext. Currently, epydoc supports two basic output formats: HTML and LaTeX.

      The HTML API documentation produced by epydoc consists of a set of HTML files, including: an API documentation page for each class and module; a syntax-highlighted source code page for each module; an identifier index page; a help page; and a frames-based table of contents. When appropriate, epydoc will also generate index pages for bugs, defined terms, and to-do items; a class hierarchy page; and a package hierarchy page.

      The LaTeX API documentation produced by epydoc consists of a main LaTeX file, and a LaTeX file for each module. If you use --dvi, --ps, or --pdf , then epydoc will invoke external commands to convert the LaTeX output to the requested format. Note that the LaTeX files containing the documentation for individual modules can be included as chapters or sections of other LaTeX documents, using the LaTeX \\include command. If you wish to include individual classes in other LaTeX documents, then use the --separate-classes option to produce a separate LaTeX file for each class.

      epydoc can also be used to check the completeness of the API documentation. By default, it checks that every public package, module, class, method, and function has a docstring description. The --tests option can be used to specify additional tests to perform.

      OPTIONS

      Epydoc's options are divided into six categories: basic options, actions, generation options, output options, graph options, and return value options.

      BASIC OPTIONS

      names...
      The list of objects that should be documented. Objects can be specified using Python dotted names (such as os.path), filenames (such as epydoc/epytext.py), or directory names (such as epydoc/). Directory names specify packages, and are expanded to include all sub-modules and sub-packages. If you wish to exclude certain sub-modules or sub-packages, use the --exclude option (described below).
      --config file
      A configuration file, specifying additional optionsand/ornames. This option may be repeated.
      --q, --quiet, --v, --verbose
      Produce quite (or verbose) output. If used multiple times, this option produces successively more quiet (or verbose) output.
      --debug
      Show full tracebacks for internal errors.
      --simple-term
      Do not try to use color or cursor control when displaying the progress bar, warnings, or errors.

      ACTIONS

      --html
      Write HTML output. [default]
      --latex
      Write LaTeX output.
      --dvi
      Write DVI output.
      --ps
      Write Postscript output.
      --pdf
      Write Adobe Acrobat (pdf) output.
      --check
      Perform completeness checks on the documentation.
      --pickle
      Write the documentation to a pickle file.

      GENERATION OPTIONS

      --docformat format
      Set the default value for __docformat__ to format. __docformat__ is a module variable that specifies the markup language for the docstrings in a module. Its value consists of the name of a markup language, optionally followed by a language code (such as en for English). For a list of the markup languages currently recognized by epydoc, run epydoc --help docformat.
      --parse-only
      Gather all information about the documented objects by parsing the relevant Python source code; in particular, do not use introspection to gather information about the documented objects. This option should be used when epydoc is run on untrusted code; or on code that can not be introspected because of missing dependencies, or because importing it would cause undesired side-effects.
      --introspect-only
      Gather all information about the documented objects by introspection; in particular, do not gather information by parsing the object's Python source code.
      --exclude PATTERN
      Do not document any object whose name matches the given regular expression pattern.
      --exclude-introspect PATTERN
      Do not use introspection to gather information about any object whose name matches the given regular expression.
      --exclude-parse PATTERN
      Do not use Python source code parsing to gather information about any object whose name matches the given regular expression.
      --inheritance format
      The format that should be used to display inherited methods, variables, and properties in the generated "summary" tables. If format is "grouped," then inherited objects are gathered into groups, based on which class that they are inherited from. If format is "listed," then inherited objects are listed in a short list at the end of the summary table. If format is "included," then inherited objects are mixed in with non-inherited objects. The default format for HTML output is "grouped."
      --show-private, --no-private
      These options control whether documentation is generated for private objects. By default, the generated documentation includes private objects, and users can choose whether to view private objects or not, by clicking on "show private" and "hide private" links. But if you want to discourage users from directly accessing private objects, then you may prefer not to generate documentation for private objects.
      --show-imports, --no-imports
      These options control whether module imports are included in the generated documentation. By default, imports are not included.
      --show-sourcecode, --no-sourcecode
      These options control whether or not epydoc should generate syntax-highlighted pages containing the souce code of each module in the HTML output. By default, the sourcecode pages are generated.
      --include-log
      Generate an HTML page epydoc-log.html containing all error and warning messages that are generated by epydoc, and include it in the generated output.

      OUTPUT OPTIONS

      -o dir, --output dir
      The output directory. If dir does not exist, then it will be created. If no output directory is specified, then the action name (e.g., html or pdf). html
      -c sheet, --css sheet
      CSS stylesheet for HTML output files. If sheet is a file, then the stylesheet is copied from that file; otherwise, sheet is taken to be the name of a built-in stylesheet. For a list of the built-in stylesheets, run epydoc --help css. If a CSS stylesheet is not specified, then the default stylesheet is used.
      -n name, --name name
      The name of the project whose documentation is being generated.
      -u url, --url url
      The URL of the project's homepage.
      --navlink html
      HTML code for the homepage link on the HTML navigation bar. If this HTML code contains any hyperlinks (<a href=...>), then it will be inserted verbatim. If it does not contain any hyperlinks, and a project url is specified (with --url), then a hyperlink to the specified URL is added to the link.
      --help-file file
      An alternate help file. file should contain the body of an HTML file -- navigation bars will be added to it.
      --show-frames, --no-frames
      These options control whether HMTL output will include a frames-base table of contents page. By default, the frames-based table of contents is included.
      --separate-classes
      In the LaTeX output, describe each class in a separate section of the documentation, instead of including them in the documentation for their modules. This creates a separate LaTeX file for each class, so it can also be useful if you want to include the documentation for one or two classes as sections of your own LaTeX document.

      GRAPH OPTIONS

      --graph graphtype
      Include graphs of type graphtype in the generated output. Graphs are generated using the Graphviz dot executable. If this executable is not on the path, then use --dotpath to specify its location. This option may be repeated to include multiple graph types in the output. graphtype should be one of: all, classtree, callgraph, or umlclasstree.
      --dotpath path
      The path to the Graphviz dot executable.
      --graph-font font
      The name of the font used to generate Graphviz graphs. (e.g., helvetica or times).
      --graph-font-size size
      The size of the font used to generate Graphviz graphs, in points.
      --pstat file
      A pstat output file, to be used in generating call graphs.

      RETURN VALUE OPTIONS

      --fail-on-error
      Return a non-zero exit status, indicating failure, if any errors are encountered.
      --fail-on-warning
      Return a non-zero exit status, indicating failure, if any errors or warnings are encountered (not including docstring warnings).
      --fail-on-docstring-warning
      Return a non-zero exit status, indicating failure, if any errors or warnings are encountered (including docstring warnings).

      HTML FILES

      The HTML API documentation produced by epydoc consists of the following files:

      OBJECT DOCUMENTATION PAGES

      index.html
      The standard entry point for the documentation. Normally, index.html is a copy of the frames file (frames.html). But if the --no-frames option is used, then index.html is a copy of the API documentation home page, which is normally the documentation page for the top-level package or module (or the trees page if there is no top-level package or module).
      module-module.html
      The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      class-class.html
      The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType.
      module-pysrc.html
      A syntax-highlighted page containing the Python source code for module. This page includes links back to the API documentation pages.
      module-tree.html
      The module hierarchy.
      class-tree.html
      The class hierarchy. This page is only generated if at least one class is documented.

      INDICES
      identifier-index.html
      An index of all documented identifiers. If the identifier index contains more than 3,000 entries, then it will be split into separate pages for each letter, named identifier-index-a.html, identifier-index-b.html, etc.
      term-index.html
      An index of all explicitly marked definitional terms. This page is only generated if at least one definition term is marked in a formatted docstring.
      bug-index.html
      An index of all explicitly marked @bug fields. This page is only generated if at least one @bug field is listed in a formatted docstring.
      todo-index.html
      An index of all explicitly marked @todo fields. This page is only generated if at least one @todo field is listed in a formatted docstring.
      changed-index.html
      An index of all explicitly marked @changed fields. This page is only generated if at least one @changed field is listed in a formatted docstring.
      deprecated-index.html
      An index of all explicitly marked @deprecated fields. This page is only generated if at least one @deprecated field is listed in a formatted docstring.
      since-index.html
      An index of all explicitly marked @since fields. This page is only generated if at least one @since field is listed in a formatted docstring.

      FRAMES-BASED TABLE OF CONTENTS

      frames.html
      The main frames file. Two frames on the left side of the window contain a table of contents, and the main frame on the right side of the window contains API documentation pages.
      toc.html
      The top-level table of contents page. This page is displayed in the upper-left frame of frames.html, and provides links to the toc-everything.html and toc-module-module.html pages.
      toc-everything.html
      The table of contents for the entire project. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the project.
      toc-module-module.html
      The table of contents for a module. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the module. module is the complete dotted name of the module, such as sys or epydoc.epytext.

      OTHER PAGES

      help.html
      The help page for the project. This page explains how to use and navigate the webpage produced by epydoc.
      redirect.html
      This page uses javascript to translate dotted names to their corresponding URLs. For example, in epydoc's documentation, loading the page <redirect.html#epydoc.apidoc.DottedName> will automatically redirect the browser to <epydoc.apidoc-module.html#DottedName>.
      epydoc.css
      The CSS stylesheet used to display all HTML pages.
      epydoc.js
      A javascript file used to define javascript functions used by epydoc.
      epydoc-log.html
      A page containing a log of all warnings and errors that were generated by epydoc, along with a table listing all of the options that were used.

      LATEX FILES

      The LaTeX API documentation produced by epydoc consists of the following files:
      api.pdf
      An Adobe Acrobat (pdf) file containing the complete API documentation. This file is only generated if you use the --pdf option.
      api.tex
      The top-level LaTeX file. This file imports the other LaTeX files, to create a single unified document.
      api.dvi
      A dvi file containing the complete API documentation. This file is only generated if you use the --dvi option, the --ps option, or the --pdf option.
      api.ps
      A postscript file containing the complete API documentation. This file is only generated if you use the --ps option or the --pdf option.
      module-module.tex
      The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      class-class.tex
      The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType. These class documentation files are only created if the --separate-classes option is used; otherwise, the documentation for each class is included in its module's documentation file.

      DIAGNOSTICS

      EPYTEXT MARKUP WARNING MESSAGES
      Epytext errors are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring. Epydoc can generate the following epytext errors:
      Bad link target.
      The target specified for an inline link contruction (L{...}) is not well-formed. Link targets must be valid python identifiers.
      Bad uri target.
      The target specified for an inline uri contruction (U{...}) is not well-formed. This typically occurs if inline markup is nested inside the URI target.
      Fields must be at the top level.
      The list of fields (@param, etc.) is contained by some other block structure (such as a list or a section).
      Fields must be the final elements.
      The list of fields (@param, etc.) is not at the end of a docstring.
      Headings must occur at top level.
      The heading is contianed in some other block structure (such as a list).
      Improper doctest block indentation.
      The doctest block dedents past the indentation of its initial prompt line.
      Improper heading indentation.
      The heading for a section is not left-aligned with the paragraphs in the section that contains it.
      Improper paragraph indentation.
      The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext.
      Invalid escape.
      An unknown escape sequence was used with the inline escape construction (E{...}).
      Lists must be indented.
      An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet.
      Unbalanced '{'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unbalanced '}'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unknown inline markup tag.
      An unknown tag was used with the inline markup construction ( x{...} ).
      Wrong underline character for heading.
      The underline character used for this section heading does not indicate an appopriate section level. The "=" character should be used to underline sections; "-" for subsections; and "~" for subsubsections.
      Possible mal-formatted field item.
      Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (":") is not included in the field tag.
      Possible heading typo.
      Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading.

      FIELD WARNINGS

      Field warnings are caused by docstrings containing invalid fields. The contents of the invalid field are generally ignored. Epydoc can generate the following field warnings:
      @param for unknown parameter param.
      A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      tag did not expect an argument.
      The field tag tag was used with an argument, but it does not take one.
      tag expected an argument.
      The field tag tag was used without an argument, but it requires one.
      @type for unknown parameter param.
      A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      @type for unknown variable var.
      A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name.
      Unknown field tag tag.
      A docstring contains a field with the unknown tag tag.
      Redefinition of field.
      Multiple field tags define the value of field in the same docstring, but field can only take a single value.

      EXAMPLES

      epydoc -n epydoc -u http://epydoc.sf.net epydoc/
      Generate the HTML API documentation for the epydoc package and all of its submodules, and write the output to the html directory. In the headers and footers, use epydoc as the project name, and http://epydoc.sf.net as the project URL.
      epydoc --pdf -n epydoc epydoc/
      Generate the LaTeX API documentation for the epydoc package and all of its submodules, and write the output to the latex directory.

      EXIT STATUS

      0
      Successful program execution.
      1
      Usage error.
      2
      Epydoc generated an error or warning, and one of the options --fail-on-error, --fail-on-warning, or --fail-on-docstring-warning was specified.
      other
      Internal error (Python exception).

      AUTHOR

      Epydoc was written by Edward Loper. This man page was originally written by Moshe Zadka, and is currently maintained by Edward Loper.

      BUGS

      Report bugs to <edloper@users.sourceforge.net>.

      SEE ALSO

      epydocgui(1)
      The epydoc webpage
      <http://epydoc.sourceforge.net>
      The epytext markup language manual
      <http://epydoc.sourceforge.net/epytext.html>


      Index

      NAME
      SYNOPSIS
      DESCRIPTION
      OPTIONS
      HTML FILES
      LATEX FILES
      DIAGNOSTICS
      EXAMPLES
      EXIT STATUS
      AUTHOR
      BUGS
      SEE ALSO

      This document was created by man2html, using the manual pages.
      Time: 01:20:48 GMT, September 24, 2007
      epydoc-3.0.1+dfsg/doc/epydoc.css0000644000175000017500000001224510750103047016740 0ustar pronovicpronovic/* * Cascading Style Sheet for edloper's webpage * Copyright (C) 2002 Edward Loper * * This stylesheet is used to give my webpage a consistant feel. * My webpage currently resides at */ /*===================================================================*/ /* Default body appearance */ body { background: #b4ccd4; color: #000000; } @media print { body { font-family: times,serif; font-size: 10pt; } } @media screen { body { background: #204060; color: #000000; } div.body { background: white; color: black; /* background: #c8e0e8; color: #000000;*/ padding: 0 1em 0 1em; border: 2px solid black; /* border: 2px groove #c0d0d0;*/ } } /*===================================================================*/ /* Headlines. */ h1 { font-size: 180%; font-weight: bold; text-align: center; padding: .1em; margin: 0; border-bottom: 2px solid black;} h2 { font-size: 150%; font-weight: bold; } h3 { font-size: 140%; font-weight: bold; font-style: italic; } h4 { font-size: 130%; font-weight: bold; font-style: italic; } /*===================================================================*/ /* Font alignment. */ .left { text-align: left; } .center { text-align: center; } .right { text-align: right; } /*===================================================================*/ /* Tables */ table { background: #ffffff; color: #000000; border: 1px solid black;} th { background: #70b0ff; color: #000000; font-weight: bold; border: 1px solid black; } td { border: 1px solid black; background: #e8f0f8; color: #000000; } th.secondary { background: #ffffff; color: #000000; font-weight: bold; font-style: italic; } /* Tables used for placement */ table.transparent { background: transparent; border-width: 0; } td.transparent { background: transparent; border-width: 0; } /* Tables used for screenshots */ .screenshot { background: #c8e0e8; color: #000000; } th.index { background: red; } /*===================================================================*/ /* Lists. */ ul.nomargin { margin-top: 0; margin-bottom: 0; } /*===================================================================*/ /* Index page. */ #documentation-box table { margin-top: 0.7em; } #documentation-box ul, #documentation-box ol { margin: 0; padding: 0 0 0 2em; font-size: 90%;} #documentation-box td { padding: 0 0 1em 0; } #documentation-box p { margin: 0; padding: 0; } #feedback-box ul { margin: 0.5em 0 0.7em 2em; padding: 0; } /*===================================================================*/ /* Link colors. */ a:link { background: transparent; color: #104060; } a:visited { background: transparent; color: #082840; } /*===================================================================*/ /* Date stamp. */ .datestamp { font-size: 70%; color: #e0f0ff; } /*===================================================================*/ /* Generic box. Usually used with DIV. */ .box { background: #e8f0f8; color: black; border: 2px solid #000000; margin: 1em 0 1em 0; padding: 0 10px 0 10px; } .box-title { background: #70b0ff; text-align: center; font-weight: bold; font-size: 125%; margin: 0 -10px 0 -10px; padding: 0 10px 0 10px; border-bottom: 2px solid black; } .doclist { padding: 0; margin: 0 0 0 1em; } .caption { font-style: italic; text-align: center; } dl.faq dt { font-weight: bold; } /*===================================================================*/ /* Screen output. */ /* - prompt: a command prompt or program prompt */ /* - user: user input */ /* - (more will be added as I use them) */ .screen { background: #e8f0f8; color: black; border: 2px solid #000000; margin: 1em 0 1em 0; padding: 0 1em 0 1em; font-family: monospace; } .screen2 { background: #c8d8e0; color: black; border: 2px solid #000000; margin: 1em 0 1em 0; padding: 0 1em 0 1em; font-family: monospace; } code.prompt { font-weight: bold; } code.user { background: transparent; color: #305040; font-style: italic; font-weight: bold; } code.string { background: transparent; color: #007000; } code.keyword { background: transparent; color: #705000; } code.function { background: transparent; color: #000080; } code.output { background: transparent; color: #505060; } code.field { background: transparent; color: #007060; } code.comment { background: transparent; color: #005080; font-style: italic; } code.pycode { background: transparent; color: #305040; } b.error { background: transparent; color: #700000; } b.error i { background: transparent; color: #604000; } /*===================================================================*/ /* Navigation box */ table.navbox { border-right: 1px solid black; border-left: 1px solid black; border-bottom: 1px solid black; } td.nav { border: 2px outset #70b0ff; background: #70b0ff; color: black; font-weight: bold; } td.navselect { background: #4888d8; color: white; } a.nav:link { text-decoration: none; } a.nav:visited { text-decoration: none; } /*===================================================================*/ /* End of stylesheet */ epydoc-3.0.1+dfsg/doc/license.html0000644000175000017500000000446610750103047017261 0ustar pronovicpronovic Epydoc License

      Epydoc License

      Epydoc is governed by the MIT open-source license:

      Permission is hereby granted, free of charge, to any person obtaining a copy of this software and any associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

      The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

      The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

      epydoc-3.0.1+dfsg/doc/fields.html0000644000175000017500000007435510750103047017111 0ustar pronovicpronovic Epydoc Fields

      Epydoc Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field consists of a tag, an optional argument, and a body.

      • The tag is a case-insensitive word that indicates what kind of documentaiton is given by the field.
      • The optional argument specifies what object, parameter, or group is documented by the field.
      • The body contains the main contents of the field.

      1. Field Markup

      Each docstring markup langauge marks fields differently. The following table shows the basic fields syntax for each markup language. For more information, see the definition of field syntax for each markup language.

      Epytext reStructuredText Javadoc
      @tag: body...
      @tag arg: body...
      :tag: body...
      :tag arg: body...
      @tag body...
      @tag arg body...
      Definition of
      epytext fields
      Definition of
      reStructuredText fields
      Definition of
      Javadoc fields

      2. Supported Fields

      The following table lists the fields that epydoc currently recognizes. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      Functions and Methods (function or method docstrings)
      @param p: ... A description of the parameter p for a function or method. It may appear in the class docstring to describe a costructor parameter: mostly useful for C extensions.
      @type p: ... The expected type for the parameter. p.
      @return: ... The return value for a function or method.
      @rtype: ... The type of the return value for a function or method.
      @keyword p: ... A description of the keyword parameter p. It may appear in the class docstring to describe a costructor keyword parameter.
      @raise e: ... A description of the circumstances under which a function or method raises exception e. It may appear in the class docstring to describe an exception that can be raised by the costructor.
      Variables (module, class or variable docstrings)
      @ivar v: ... A description of the class instance variable v.
      @cvar v: ... A description of the static class variable v.
      @var v: ... A description of the module variable v.
      @type v: ... The type of the variable v.
      Properties (property docstrings)
      @type: ... The type of the property.
      Grouping and Sorting (module, class, function, or method docstrings)
      @group gc1,...,cn Organizes a set of related children of a module or class into a group. g is the name of the group; and c1,...,cn are the names of the children in the group. To define multiple groups, use multiple group fields.
      @sortc1,...,cn Specifies the sort order for the children of a module or class. c1,...,cn are the names of the children, in the order in which they should appear. Any children that are not included in this list will appear after the children from this list, in alphabetical order.
      Related Topics
      @see: ... A description of a related topic. see fields typically use documentation crossreference links or external hyperlinks that link to the related topic.
      Notes and Warnings
      @note: ... A note about an object. Multiple note fields may be used to list separate notes.
      @attention: ... An important note about an object. Multiple attention fields may be used to list separate notes.
      @bug: ... A description of a bug in an object. Multiple bug fields may be used to report separate bugs.
      @warning: ... A warning about an object. Multiple warning fields may be used to report separate warnings.
      Status
      @version: ... The current version of an object.
      @todo [ver]: ... A planned change to an object. If the optional argument ver is given, then it specifies the version for which the change will be made. Multiple todo fields may be used if multiple changes are planned.
      @deprecated: ... Indicates that an object is deprecated. The body of the field describe the reason why the object is deprecated.
      @since: ... The date or version when an object was first introduced.
      @status: ... The current status of an object.
      @change: ... A change log entry for this object.
      @permission: ... The object access permission, for systems such Zope/Plone supporting this concept. It may be used more than once to specify multiple permissions.
      Formal Conditions
      @requires: ... A requirement for using an object. Multiple requires fields may be used if an object has multiple requirements.
      @precondition: ... A condition that must be true before an object is used. Multiple precondition fields may be used if an object has multiple preconditions.
      @postcondition: ... A condition that is guaranteed to be true after an object is used. Multiple postcondition fields may be used if an object has multiple postconditions.
      @invariant: ... A condition which should always be true for an object. Multiple invariant fields may be used if an object has multiple invariants.
      Bibliographic Information
      @author: ... The author(s) of an object. Multiple author fields may be used if an object has multiple authors.
      @organization: ... The organization that created or maintains an object.
      @copyright: ... The copyright information for an object.
      @license: ... The licensing information for an object.
      @contact: ... Contact information for the author or maintainer of a module, class, function, or method. Multiple contact fields may be used if an object has multiple contacts.
      Summarization
      @summary: ... A summary description for an object. This description overrides the default summary (which is constructed from the first sentence of the object's description).

      2.1. Notes on Supported Fields

      • @param fields should be used to document any explicit parameter (including the keyword parameter). @keyword fields should only be used for non-explicit keyword parameters:

        def plant(seed, *tools, **options):
            """
            @param seed: The seed that should be planted.
            @param tools: Tools that should be used to plant the seed.
            @param options: Any extra options for the planting.
        
            @keyword dig_deep: Plant the seed deep under ground.
            @keyword soak: Soak the seed before planting it.
            """
            [...]
        
      • For the @group and @sort tags, asterisks (*) can be used to specify multiple children at once. An asterisk in a child name will match any substring:

        class widget(size, weight, age):
            """
            @group Tools: zip, zap, *_tool
            @group Accessors: get_*
            @sort: get_*, set_*, unpack_*, cut
            """
            [...]
        
      • Since the @type field allows for arbitrary text, it does not automatically create a crossreference link to the specified type, and is not written in fixed-width font by default. If you want to create a crossreference link to the type, or to write the type in a fixed-width font, then you must use inline markup:

        def ponder(person, time):
            """
            @param person: Who should think.
            @type person: L{Person} or L{Animal}
            @param time: How long they should think.
            @type time: C{int} or C{float}
            """
            [...]
        

      3. Where to Write Fields

      Normally the fields are written in the docstring of the documented objects: this allows you to add fields to modules, classes, function, properties. Where a docstring is not allowed, usually alternative options do exist.

      3.1. Variable docstrings

      Python variables don't support docstrings. The variable can be described in the module or class where it is defined using the tags @var, @ivar, @cvar; but this only allows for a textual description: no further metadata can be added to the variable (except for the type, using the @type tag.

      Epydoc supports variable docstrings: if a variable assignment statement is immediately followed by a bare string literal, then that assignment is treated as a docstring for that variable. In classes, variable assignments at the class definition level are considered class variables; and assignments to instance variables in the constructor (__init__) are considered instance variables:

      >>> class A:
      ...     x = 22
      ...     """Docstring for class variable A.x"""
      ...
      ...     def __init__(self, a):
      ...         self.y = a
      ...         """Docstring for instance variable A.y
      

      Variables may also be documented using comment docstrings. If a variable assignment is immediately preceeded by a comment whose lines begin with the special marker "#:", or is followed on the same line by such a comment, then it is treated as a docstring for that variable:

      >>> #: docstring for x
      ... x = 22
      >>> x = 22 #: docstring for x
      

      A common Python idiom is to create instance variables settings their default value in the class instead of the constructor (hopefully if the default is immutable...). To avoid Epydoc to interpret such variable as a class variable, you can describe it using the tag @ivar in the context of a variable docstring:

      >>> class B:
      ...     y = 42
      ...     """@ivar: This is an instance variable."""
      

      Notice that variable docstrings are only available for documentation when the source code is available for parsing: it is not possible to retrieve variable docstrings from introspection informations only.

      3.2. C Extensions

      In a C extension module, extension classes cannot have a docstring attached to the __init__ function; consequently it is not possible to document parameters and exceptions raised by the class constructor. To overcome this shortcoming, the tags @param, @keyword, @type, @exception are allowed to appear in the class docstring to refer to constructor parameters.

      4. Field Synonyms

      Several fields have "synonyms," or alternate tags. The following table lists all field synonyms. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      NameSynonyms
      @param p: ... @parameter p: ...
      @arg p: ...
      @argument p: ...
      @return: ... @returns: ...
      @rtype: ... @returntype: ...
      @raise e: ... @raises e: ...
      @except e: ...
      @exception e: ...
      @keyword p: ... @kwarg p: ...
      @kwparam p: ...
      @ivar v: ... @ivariable v: ...
      @cvar v: ... @cvariable v: ...
      NameSynonyms
      @var v: ... @variable v: ...
      @see: ... @seealso: ...
      @warning: ... @warn: ...
      @requires: ... @require: ...
      @requirement: ...
      @precondition: ... @precond: ...
      @postcondition: ... @postcod: ...
      @organization: ... @org: ...
      @copyright: ... @(c): ...
      @change: ... @changed: ...

      4.1. Metadata variables

      Some module variables are commonly used as module metadata. Epydoc can use the value provided by these variables as alternate form for tags. The following table lists the recognized variables and the tag they replace. Customized metadata variables can be added using the method described in Adding New Fields.

      TagVariable
      @deprecated __deprecated__
      @version __version__
      @date __date__
      @author
      @authors
      __author__
      __authors__
      @contact __contact__
      @copyright __copyright__
      @license __license__

      5. Adding New Fields

      New fields can be defined for the docstrings in a module using the special @newfield tag (or its synonym, @deffield). This tag has the following syntax:

      @newfield tag: label [, plural]
      

      Where tag is the new tag that's being defined; label is a string that will be used to mark this field in the generated output; and plural is the plural form of label, if different.

      It will also be possibile to use the module variable __tag__ to set the value for the newly defined tag.

      The following example illustrates how the @newfield can be used:

      Docstring InputRendered Output
      """
      @newfield corpus: Corpus, Corpora
      """
      
      def example():
          """
          @corpus: Bob's wordlist.
          @corpus: The British National Corpus.
          """
          [...]
      

      Corpora:

      • Bob's wordlist.
      • The British National Corpus.

      Note: The module-level variable __extra_epydoc_fields__ is deprecated; use @newfield instead.

      6. Markup-Specific Notes

      For the most part, fields are treated identically, regardless of what markup language is used to encode them. However, there are a few minor differences, which are intended to accomodate existing standards for each markup language. In particular:

      • reStructuredText supports an extra group of fields, called consolidated fields, which combine the documentation for several objects into a single field.
      • Javadoc uses a special syntax for the body of the @see fields.
      • Javadoc does not support multi-word arguments.

      For more information about these differences, read the subsections below.

      6.1. reStructuredText Fields

      In reStructuredText, a single field can be used to encode the documentation for a group of related items. For example, a single :Parameters: field is often used to describe all of the parameters for a function or method:

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
            - `size`: The size of the fox (in meters)
            - `weight`: The weight of the fox (in stones)
            - `age`: The age of the fox (in years)
          """
          [...]
      

      Epydoc will automatically extract information about each parameter from this list. These consolidated fields may be written using either a bulleted list or a definition list. If a consolidated field is written as a bulleted list, then each list item must begin with the field's argument, marked as interpreted text, and followed by a colon or dash. If a consolidated field is written as a definition list, then each definition item's term should contain the field's argument, (it is not mandatory for it being marked as interpreted text). The term classifier, if present, is used to specify the associated type. The following example shows the use of a definition list to define a consolidated field. (Note that docutils requires a space before and after the ":" used to mark classifiers.)

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
            size
                The size of the fox (in meters)
            weight : float
                The weight of the fox (in stones)
            age : int
                The age of the fox (in years)
          """
          [...]
      

      The following consolidated fields are currently supported by epydoc:

      Consolidated
      Field Tag
      Corresponding
      Base Field Tag
      :Parameters: :param:
      :Exceptions: :except:
      :Groups: :group:
      :Keywords: :keyword:
      Consolidated
      Field Tag
      Corresponding
      Base Field Tag
      :Variables: :var:
      :Ivariables: :ivar:
      :Cvariables: :cvar:
      :Types: :type:

      6.2. Javadoc Fields

      For compatibility with Javadoc, every @see field is assumed to contain a single crossreference link, unless its body is quoted, or it starts with an HTML tag. See the Javadoc reference manual for more information about how the @see field is encoded in Javadoc.

      Because Javadoc does not mark end of the optional argument, field arguments must contain exactly one word. Thus, multi-word arguments are not available in Javadoc. In particular, all group names must be single words.

      epydoc-3.0.1+dfsg/doc/manual-epytext.html0000644000175000017500000013456510750103050020612 0ustar pronovicpronovic The Epytext Markup Language

      The Epytext Markup Language

      A Brief Introduction

      Epytext is a simple lightweight markup language that lets you add formatting and structue to docstrings. Epydoc uses that formatting and structure to produce nicely formatted API documentation. The following example (which has an unusually high ratio of documentaiton to code) illustrates some of the basic features of epytext:

      def x_intercept(m, b):
          """
          Return the x intercept of the line M{y=m*x+b}.  The X{x intercept}
          of a line is the point at which it crosses the x axis (M{y=0}).
      
          This function can be used in conjuction with L{z_transform} to
          find an arbitrary function's zeros.
      
          @type  m: number
          @param m: The slope of the line.
          @type  b: number
          @param b: The y intercept of the line.  The X{y intercept} of a
                    line is the point at which it crosses the y axis (M{x=0}).
          @rtype:   number
          @return:  the x intercept of the line M{y=m*x+b}.
          """
          return -b/m

      You can compare this function definition with the API documentation generated by epydoc. Note that:

      • Paragraphs are separated by blank lines.
      • Inline markup has the form "x{...}", where "x" is a single capital letter. This example uses inline markup to mark mathematical expressions ("M{...}"); terms that should be indexed ("X{...}"); and links to the documentation of other objects ("L{...}").
      • Descriptions of parameters, return values, and types are marked with "@field:" or "@field arg:", where "field" identifies the kind of description, and "arg" specifies what object is described.

      Epytext is intentionally very lightweight. If you wish to use a more expressive markup language, I recommend reStructuredText.

      Epytext Language Overview

      Epytext is a lightweight markup language for Python docstrings. The epytext markup language is used by epydoc to parse docstrings and create structured API documentation. Epytext markup is broken up into the following categories:

      • Block Structure divides the docstring into nested blocks of text, such as paragraphs and lists.

        o Basic Blocks are the basic unit of block structure.

        o Hierarchical blocks represent the nesting structure of the docstring.

      • Inline Markup marks regions of text within a basic block with properties, such as italics and hyperlinks.

      Block Structure

      Block structure is encoded using indentation, blank lines, and a handful of special character sequences.

      • Indentation is used to encode the nesting structure of hierarchical blocks. The indentation of a line is defined as the number of leading spaces on that line; and the indentation of a block is typically the indentation of its first line.
      • Blank lines are used to separate blocks. A blank line is a line that only contains whitespace.
      • Special character sequences are used to mark the beginnings of some blocks. For example, '-' is used as a bullet for unordered list items, and '>>>' is used to mark doctest blocks.

      The following sections describe how to use each type of block structure.

      Paragraphs

      A paragraph is the simplest type of basic block. It consists of one or more lines of text. Paragraphs must be left justified (i.e., every line must have the same indentation). The following example illustrates how paragraphs can be used:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.  Paragraphs can
          span multiple lines, and can contain
          I{inline markup}.
      
          This is another paragraph.  Paragraphs
          are separated by blank lines.
          """
          *[...]*

      This is a paragraph. Paragraphs can span multiple lines, and contain inline markup.

      This is another paragraph. Paragraphs are separated from each other by blank lines.

      Lists

      Epytext supports both ordered and unordered lists. A list consists of one or more consecutive list items of the same type (ordered or unordered), with the same indentation. Each list item is marked by a bullet. The bullet for unordered list items is a single dash character (-). Bullets for ordered list items consist of a series of numbers followed by periods, such as 12. or 1.2.8..

      List items typically consist of a bullet followed by a space and a single paragraph. The paragraph may be indented more than the list item's bullet; often, the paragraph is intended two or three characters, so that its left margin lines up with the right side of the bullet. The following example illustrates a simple ordered list.

      Docstring Input Rendered Output
      def example():
          """
          1. This is an ordered list item.
      
          2. This is a another ordered list
          item.
      
          3. This is a third list item.  Note that
             the paragraph may be indented more
             than the bullet.
          """
          *[...]*
      1. This is an ordered list item.
      2. This is another ordered list item.
      3. This is a third list item. Note that the paragraph may be indented more than the bullet.

      List items can contain more than one paragraph; and they can also contain sublists, literal blocks, and doctest blocks. All of the blocks contained by a list item must all have equal indentation, and that indentation must be greater than or equal to the indentation of the list item's bullet. If the first contained block is a paragraph, it may appear on the same line as the bullet, separated from the bullet by one or more spaces, as shown in the previous example. All other block types must follow on separate lines.

      Every list must be separated from surrounding blocks by indentation:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
            2. This a second list
               item.
                 - This is a sublist
          """
          [...]

      This is a paragraph.

      1. This is a list item.
      2. This is a second list item.
        • This is a sublist.

      Note that sublists must be separated from the blocks in their parent list item by indentation. In particular, the following docstring generates an error, since the sublist is not separated from the paragraph in its parent list item by indentation:

      Docstring Input Rendered Output
      def example():
          """
          1. This is a list item.  Its
          paragraph is indented 7 spaces.
          - This is a sublist.  It is
            indented 7 spaces.
          """
          #[...]
      L5: Error: Lists must be indented.

      The following example illustrates how lists can be used:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
              - This is a sublist.
              - The sublist contains two
                items.
                  - The second item of the
                    sublist has its own sublist.
      
            2. This list item contains two
               paragraphs and a doctest block.
      
               >>> print 'This is a doctest block'
               This is a doctest block
      
               This is the second paragraph.
          """
          #[...]

      This is a paragraph.

      1. This is a list item.

        • This is a sublist.
        • The sublist contains two items.
          • The second item of the sublist has its own own sublist.
      2. This list item contains two paragraphs and a doctest block.

        >>> print 'This is a doctest block'
        This is a doctest block

        This is the second paragraph.

      Epytext will treat any line that begins with a bullet as a list item. If you want to include bullet-like text in a paragraph, then you must either ensure that it is not at the beginning of the line, or use escaping to prevent epytext from treating it as markup:

      Docstring Input Rendered Output
      def example():
          """
          This sentence ends with the number
          1.  Epytext can't tell if the "1."
          is a bullet or part of the paragraph,
          so it generates an error.
          """
          #[...]
      L4: Error: Lists must be indented.
      def example():
          """
          This sentence ends with the number 1.
      
          This sentence ends with the number
          E{1}.
          """
          #[...]

      This sentence ends with the number 1.

      This sentence ends with the number 1.

      Sections

      A section consists of a heading followed by one or more child blocks.

      • The heading is a single underlined line of text. Top-level section headings are underlined with the '=' character; subsection headings are underlined with the '-' character; and subsubsection headings are underlined with the '~' character. The length of the underline must exactly match the length of the heading.
      • The child blocks can be paragraphs, lists, literal blocks, doctest blocks, or sections. Each child must have equal indentation, and that indentation must be greater than or equal to the heading's indentation.

      The following example illustrates how sections can be used:

      Docstring Input Rendered Output
      def example():
          """
          This paragraph is not in any section.
      
          Section 1
          =========
            This is a paragraph in section 1.
      
            Section 1.1
            -----------
            This is a paragraph in section 1.1.
      
          Section 2
          =========
            This is a paragraph in section 2.
          """
          #[...]

      Section 1

      This is a paragraph in section 1.

      Section 1.1

      This is a paragraph in section 1.1.

      Section 2

      This is a paragraph in section 2.

      Literal Blocks

      Literal blocks are used to represent "preformatted" text. Everything within a literal block should be displayed exactly as it appears in plaintext. In particular:

      • Spaces and newlines are preserved.
      • Text is shown in a monospaced font.
      • Inline markup is not detected.

      Literal blocks are introduced by paragraphs ending in the special sequence "::". Literal blocks end at the first line whose indentation is equal to or less than that of the paragraph that introduces them. The following example shows how literal blocks can be used:

      Docstring Input Rendered Output
      def example():
          """
          The following is a literal block::
      
              Literal /
                     / Block
      
          This is a paragraph following the
          literal block.
          """
          #[...]

      The following is a literal block:

      Literal /
             / Block
      

      This is a paragraph following the literal block.

      Literal blocks are indented relative to the paragraphs that introduce them; for example, in the previous example, the word "Literal" is displayed with four leading spaces, not eight. Also, note that the double colon ("::") that introduces the literal block is rendered as a single colon.

      Doctest Blocks

      Doctest blocks contain examples consisting of Python expressions and their output. Doctest blocks can be used by the doctest module to test the documented object. Doctest blocks begin with the special sequence ">>>". Doctest blocks are delimited from surrounding blocks by blank lines. Doctest blocks may not contain blank lines. The following example shows how doctest blocks can be used:

      Docstring Input Rendered Output
      def example():
          """
          The following is a doctest block:
      
              >>> print (1+3,
              ...        3+5)
              (4, 8)
              >>> 'a-b-c-d-e'.split('-')
              ['a', 'b', 'c', 'd', 'e']
      
          This is a paragraph following the
          doctest block.
          """
          #[...]

      The following is a doctest block:

      >>> print (1+3,
      ...        3+5)
      (4, 8)
      >>> 'a-b-c-d-e'.split('-')
      ['a', 'b', 'c', 'd', 'e']

      This is a paragraph following the doctest block.

      Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field is marked by a field tag, which consist of an at sign ('@') followed by a field name, optionally followed by a space and a field argument, followed by a colon (':'). For example, '@return:' and '@param x:' are field tags.

      Fields can contain paragraphs, lists, literal blocks, and doctest blocks. All of the blocks contained by a field must all have equal indentation, and that indentation must be greater than or equal to the indentation of the field's tag. If the first contained block is a paragraph, it may appear on the same line as the field tag, separated from the field tag by one or more spaces. All other block types must follow on separate lines.

      Fields must be placed at the end of the docstring, after the description of the object. Fields may be included in any order.

      Fields do not need to be separated from other blocks by a blank line. Any line that begins with a field tag followed by a space or newline is considered a field.

      The following example illustrates how fields can be used:

      Docstring Input Rendered Output
      def example():
          """
          @param x: This is a description of
              the parameter x to a function.
              Note that the description is
              indented four spaces.
          @type x: This is a description of
              x's type.
          @return: This is a description of
              the function's return value.
      
              It contains two paragraphs.
          """
          #[...]
      Parameters:

      x - This is a description of the parameter x to a function. Note that the description is indented four spaces.

      (type=This is a description of x's type.)
      Returns:

      This is a description of the function's return value.

      It contains two paragraphs.

      For a list of the fields that are supported by epydoc, see the epydoc fields chapter.

      Inline Markup

      Inline markup has the form 'x{...}', where x is a single capital letter that specifies how the text between the braces should be rendered. Inline markup is recognized within paragraphs and section headings. It is not recognized within literal and doctest blocks. Inline markup can contain multiple words, and can span multiple lines. Inline markup may be nested.

      A matching pair of curly braces is only interpreted as inline markup if the left brace is immediately preceeded by a capital letter. So in most cases, you can use curly braces in your text without any form of escaping. However, you do need to escape curly braces when:

      1. You want to include a single (un-matched) curly brace.
      2. You want to preceed a matched pair of curly braces with a capital letter.

      Note that there is no valid Python expression where a pair of matched curly braces is immediately preceeded by a capital letter (except within string literals). In particular, you never need to escape braces when writing Python dictionaries. See also escaping.

      Basic Inline Markup

      Epytext defines four types of inline markup that specify how text should be displayed:
      • I{...}: Italicized text.
      • B{...}: Bold-faced text.
      • C{...}: Source code or a Python identifier.
      • M{...}: A mathematical expression.

      By default, source code is rendered in a fixed width font; and mathematical expressions are rendered in italics. But those defaults may be changed by modifying the CSS stylesheet. The following example illustrates how the four basic markup types can be used:

      Docstring Input Rendered Output
      def example():
          """
          I{B{Inline markup} may be nested; and
          it may span} multiple lines.
      
            - I{Italicized text}
            - B{Bold-faced text}
            - C{Source code}
            - M{Math}
      
          Without the capital letter, matching
          braces are not interpreted as markup:
          C{my_dict={1:2, 3:4}}.
          """
          #[...]

      Inline markup may be nested; and it may span multiple lines.

      • Italicized text
      • Bold-faced text
      • Source code
      • Math: m*x+b

      Without the capital letter, matching braces are not interpreted as markup: my_dict={1:2, 3:4}.

      URLs

      The inline markup construct U{text<url>} is used to create links to external URLs and URIs. 'text' is the text that should be displayed for the link, and 'url' is the target of the link. If you wish to use the URL as the text for the link, you can simply write "U{url}". Whitespace within URL targets is ignored. In particular, URL targets may be split over multiple lines. The following example illustrates how URLs can be used:

      Docstring Input Rendered Output
      def example():
          """
          - U{www.python.org}
          - U{http://www.python.org}
          - U{The epydoc homepage<http://
          epydoc.sourceforge.net>}
          - U{The B{Python} homepage
          <www.python.org>}
          - U{Edward Loper<mailto:edloper@
          gradient.cis.upenn.edu>}
          """
          #[...]

      Indexed Terms

      Epydoc automatically creates an index of term definitions for the API documentation. The inline markup construct 'X{...}' is used to mark terms for inclusion in the index. The term itself will be italicized; and a link will be created from the index page to the location of the term in the text. The following example illustrates how index terms can be used:

      Docstring Input Rendered Output
      def example():
          """
          An X{index term} is a term that
          should be included in the index.
          """
          #[...]

      An index term is a term that should be included in the index.

      Index
      index term example
      x intercept x_intercept
      y intercept x_intercept

      Symbols

      Symbols are used to insert special characters in your documentation. A symbol has the form 'S{code}', where code is a symbol code that specifies what character should be produced. The following example illustrates how symbols can be used to generate special characters:

      Docstring Input Rendered Output
      def example():
          """
          Symbols can be used in equations:
      
            - S{sum}S{alpha}/x S{<=} S{beta}
      
          S{<-} and S{larr} both give left
          arrows.  Some other arrows are
          S{rarr}, S{uarr}, and S{darr}.
          """
          #[...]

      Symbols can be used in equations:

      • ∑ α/x ≤ β

      ← and ← both give left arrows. Some other arrows are →, ↑, and ↓.

      Although symbols can be quite useful, you should keep in mind that they can make it harder to read your docstring in plaintext. In general, symbols should be used sparingly. For a complete list of the symbols that are currently supported, see the reference documentation for epytext.SYMBOLS.

      Escaping

      Escaping is used to write text that would otherwise be interpreted as epytext markup. Epytext was carefully constructed to minimize the need for this type of escaping; but sometimes, it is unavoidable. Escaped text has the form 'E{code}', where code is an escape code that specifies what character should be produced. If the escape code is a single character (other than '{' or '}'), then that character is produced. For example, to begin a paragraph with a dash (which would normally signal a list item), write 'E{-}'. In addition, two special escape codes are defined: 'E{lb}' produces a left curly brace ('{'); and 'E{rb}' produces a right curly brace ('}'). The following example illustrates how escaping can be used:

      Docstring Input Rendered Output
      def example():
          """
          This paragraph ends with two
          colons, but does not introduce
          a literal blockE{:}E{:}
      
          E{-} This is not a list item.
      
          Escapes can be used to write
          unmatched curly braces:
          E{rb}E{lb}
          """
          #[...]

      This paragraph ends with two colons, but does not introduce a literal block::

      - This is not a list item.

      Escapes can be used to write unmatched curly braces: }{

      Graphs

      The inline markup construct 'G{graphtype args...}' is used to insert automatically generated graphs. The following graphs generation constructions are currently defines:

      Markup Description
      G{classtree classes...} Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed.
      G{packagetree modules...} Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed.
      G{importgraph modules...} Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed.
      G{callgraph functions...} Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed.

      Characters

      Valid Characters

      Valid characters for an epytext docstring are space (\040); newline (\012); and any letter, digit, or punctuation, as defined by the current locale. Control characters (\000-\010` and ``\013-\037) are not valid content characters. Tabs (\011) are expanded to spaces, using the same algorithm used by the Python parser. Carridge-return/newline pairs (\015\012) are converted to newlines.

      Content Characters

      Characters in a docstring that are not involved in markup are called content characters. Content characters are always displayed as-is. In particular, HTML codes are not passed through. For example, consider the following example:

      Docstring Input Rendered Output
      def example():
          """
          <B>test</B>
          """
          #[...]
      <B>test</B>

      The docstring is rendered as <B>test</B>, and not as the word "test" in bold face.

      Spaces and Newlines

      In general, spaces and newlines within docstrings are treated as soft spaces. In other words, sequences of spaces and newlines (that do not contain a blank line) are rendered as a single space, and words may wrapped at spaces. However, within literal blocks and doctest blocks, spaces and newlines are preserved, and no word-wrapping occurs; and within URL targets and documentation link targets, whitespace is ignored.

      epydoc-3.0.1+dfsg/doc/index.html0000644000175000017500000001554310750103047016744 0ustar pronovicpronovic Epydoc

      Epydoc

      Automatic API Documentation Generation for Python

      Overview

      Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc's output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc's output, see the API documentation for Python 2.5.

      Latest Release

      The latest stable release is Epydoc 3.0. If you wish to keep up on the latest developments, you can also get epydoc from the subversion repository. See Installing Epydoc for more information.

      Screenshots

      Generated HTML documentation for epydoc
      Example of a UML graph generated by epydoc
      Example of syntax highlighted source, w/ links to API docs
      Identifier index page for generated Python 2.4 docs

      News

      Epydoc 3.0 released [January 2008]
      Epydoc version 3.0 is now available on the SourceForge download page. See the What's New page for details. Epydoc is under active development; if you wish to keep up on the latest developments, you can get epydoc from the subversion repository. If you find any bugs, or have suggestions for improving it, please report them on sourceforge.

      Presentation at PyCon [March 2004]
      Epydoc was presented at PyCon by Edward Loper. Video and audio from the presentation are available for download.

      epydoc-3.0.1+dfsg/doc/manual-fields.html0000644000175000017500000006723510750103050020355 0ustar pronovicpronovic Epydoc Fields

      Epydoc Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field consists of a tag, an optional argument, and a body.

      • The tag is a case-insensitive word that indicates what kind of documentation is given by the field.
      • The optional argument specifies what object, parameter, or group is documented by the field.
      • The body contains the main contents of the field.

      Field Markup

      Each docstring markup langauge marks fields differently. The following table shows the basic fields syntax for each markup language. For more information, see the definition of field syntax for each markup language.

      Epytext reStructuredText Javadoc
      @tag: body...
      @tag arg: body...
      
      :tag: body...
      :tag arg: body...
      
      @tag body...
      @tag arg body...
      
      Definition of epytext fields Definition of ReStructuredText fields Definition of Javadoc fields

      Supported Fields

      The following table lists the fields that epydoc currently recognizes. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      Functions and Methods parameters

      @param p: ...
      A description of the parameter p for a function or method.
      @type p: ...
      The expected type for the parameter p.
      @return: ...
      The return value for a function or method.
      @rtype: ...
      The type of the return value for a function or method.
      @keyword p: ...
      A description of the keyword parameter p.
      @raise e: ...
      A description of the circumstances under which a function or method raises exception e.

      These tags can be used to specify attributes of parameters and return value of function and methods. These tags are usually put in the the docstring of the function to be documented.

      Note

      constructor parameters

      In C extension modules, extension classes cannot have a docstring attached to the __init__ function; consequently it is not possible to document parameters and exceptions raised by the class constructor. To overcome this shortcoming, the tags @param, @keyword, @type, @exception are also allowed to appear in the class docstring. In this case they refer to constructor parameters.

      @param fields should be used to document any explicit parameter (including the keyword parameter). @keyword fields should only be used for non-explicit keyword parameters:

      def plant(seed, *tools, **options):
          """
          @param seed: The seed that should be planted.
          @param tools: Tools that should be used to plant the seed.
          @param options: Any extra options for the planting.
      
          @keyword dig_deep: Plant the seed deep under ground.
          @keyword soak: Soak the seed before planting it.
          """
          #[...]

      Since the @type field allows for arbitrary text, it does not automatically create a crossreference link to the specified type, and is not written in fixed-width font by default. If you want to create a crossreference link to the type, or to write the type in a fixed-width font, then you must use inline markup:

      def ponder(person, time):
          """
          @param person: Who should think.
          @type person: L{Person} or L{Animal}
          @param time: How long they should think.
          @type time: C{int} or C{float}
          """
          #[...]

      Variables parameters

      @ivar v: ...
      A description of the class instance variable v.
      @cvar v: ...
      A description of the static class variable v.
      @var v: ...
      A description of the module variable v.
      @type v: ...
      The type of the variable v.

      These tags are usually put in a module or class docstring. If the sources can be parsed by Epydoc it is also possible to document the variable in their own docstrings: see variable docstrings

      Epydoc considers class variables the ones defined directly defined in the class body. A common Python idiom is to create instance variables settings their default value in the class instead of the constructor (hopefully if the default is immutable...).

      If you want to force Epydoc to classify as instance variable one whose default value is set at class level, you can describe it using the tag @ivar in the context of a variable docstring:

      class B:
          y = 42
          """@ivar: This is an instance variable."""

      Properties parameters

      @type: ...
      The type of the property.

      The @type tag can be attached toa property docstring to specify its type.

      Grouping and Sorting

      @group g: c1,...,cn
      Organizes a set of related children of a module or class into a group. g is the name of the group; and c1,...,cn are the names of the children in the group. To define multiple groups, use multiple group fields.
      @sort: c1,...,cn
      Specifies the sort order for the children of a module or class. c1,...,cn are the names of the children, in the order in which they should appear. Any children that are not included in this list will appear after the children from this list, in alphabetical order.

      These tags can be used to present groups of related items in a logical way. They apply to modules and classes docstrings.

      For the @group and @sort tags, asterisks (*) can be used to specify multiple children at once. An asterisk in a child name will match any substring:

      class widget(size, weight, age):
          """
          @group Tools: zip, zap, *_tool
          @group Accessors: get_*
          @sort: get_*, set_*, unpack_*, cut
          """
          #[...]

      Note

      group markers

      It is also possible to group set of related items enclosing them into special comment starting with the group markers '#{' and '#}' The group title can be specified after the opening group marker. Example:

      #{ Database access functions
      
      def read(id):
          #[...]
      
      def store(item):
          #[...]
      
      def delete(id):
          #[...]
      
      # groups can't be nested, so a closing marker is not required here.
      
      #{ Web publish functions
      
      def get(request):
          #[...]
      
      def post(request):
          #[...]
      
      #}

      Notes and Warnings

      @note: ...
      A note about an object. Multiple note fields may be used to list separate notes.
      @attention: ...
      An important note about an object. Multiple attention fields may be used to list separate notes.
      @bug: ...

      A description of a bug in an object. Multiple bug fields may be used to report separate bugs.

      Note

      If any @bug field is used, the HTML writer will generate a the page bug-index.html, containing links to all the items tagged with the field.

      @warning: ...
      A warning about an object. Multiple warning fields may be used to report separate warnings.

      Status

      @version: ...
      The current version of an object.
      @todo [ver]: ...

      A planned change to an object. If the optional argument ver is given, then it specifies the version for which the change will be made. Multiple todo fields may be used if multiple changes are planned.

      Note

      If any @todo field is used, the HTML writer will generate a the page todo-index.html, containing links to all the items tagged with the field.

      @deprecated: ...
      Indicates that an object is deprecated. The body of the field describe the reason why the object is deprecated.
      @since: ...
      The date or version when an object was first introduced.
      @status: ...
      The current status of an object.
      @change: ...
      A change log entry for this object.
      @permission: ...
      The object access permission, for systems such Zope/Plone supporting this concept. It may be used more than once to specify multiple permissions.

      Formal Conditions

      @requires: ...
      A requirement for using an object. Multiple requires fields may be used if an object has multiple requirements.
      @precondition: ...
      A condition that must be true before an object is used. Multiple precondition fields may be used if an object has multiple preconditions.
      @postcondition: ...
      A condition that is guaranteed to be true after an object is used. Multiple postcondition fields may be used if an object has multiple postconditions.
      @invariant: ...
      A condition which should always be true for an object. Multiple invariant fields may be used if an object has multiple invariants.

      Bibliographic Information

      @author: ...
      The author(s) of an object. Multiple author fields may be used if an object has multiple authors.
      @organization: ...
      The organization that created or maintains an object.
      @copyright: ...
      The copyright information for an object.
      @license: ...
      The licensing information for an object.
      @contact: ...
      Contact information for the author or maintainer of a module, class, function, or method. Multiple contact fields may be used if an object has multiple contacts.

      Other fields

      @summary: ...
      A summary description for an object. This description overrides the default summary (which is constructed from the first sentence of the object's description).
      @see: ...
      A description of a related topic. see fields typically use documentation crossreference links or external hyperlinks that link to the related topic.

      Fields synonyms

      Several fields have synonyms, or alternate tags. The following table lists all field synonyms. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      Name Synonims
      @param p: ...
      @parameter p: ...
      @arg p: ...
      @argument p: ...
      @return: ... @returns: ...
      @rtype: ... @returntype: ...
      @raise e: ...
      @raises e: ...
      @except e: ...
      @exception e: ...
      @keyword p: ...
      @kwarg p: ...
      @kwparam p: ...
      @ivar v: ... @ivariable v: ...
      @cvar v: ... @cvariable v: ...
      @var v: ... @variable v: ...
      @see: ... @seealso: ...
      @warning: ... @warn: ...
      @requires: ...
      @require: ...
      @requirement: ...
      @precondition: ... @precond: ...
      @postcondition: ... @postcond: ...
      @organization: ... @org: ...
      @copyright: ... @(c): ...
      @change: ... @changed: ...

      Module metadata variables

      Some module variables are commonly used as module metadata. Epydoc can use the value provided by these variables as alternate form for tags. The following table lists the recognized variables and the tag they replace. Customized metadata variables can be added using the method described in Adding New Fields.

      Tag Variable
      @author __author__
      @authors __authors__
      @contact __contact__
      @copyright __copyright__
      @license __license__
      @deprecated __deprecated__
      @date __date__
      @version __version__

      Adding New Fields

      New fields can be defined for the docstrings in a module using the special @newfield tag (or its synonym, @deffield). This tag has the following syntax:

      @newfield tag: label [, plural ]
      

      Where tag is the new tag that's being defined; label is a string that will be used to mark this field in the generated output; and plural is the plural form of label, if different.

      New fields can be defined in any Python module. If they are defined in a package, it will be possible to use the newly defined tag from every package submodule.

      Each new field will also define a metadata variable which can be used to set the field value instead of the tag. For example, if a revision tag has been defined with:

      @newfield revision: Revision
      

      then it will be possible to set a value for the field using a module variable:

      __revision__ = "1234"

      The following example illustrates how the @newfield can be used: Docstring Input Rendered Output

      Docstring Input Rendered Output
      """
      @newfield corpus: Corpus, Corpora
      """
      
      def example():
          """
          @corpus: Bob's wordlist.
          @corpus: The British National Corpus.
          """
          [...]

      Corpora:

      • Bob's wordlist.
      • The British National Corpus.

      Note

      The module-level variable __extra_epydoc_fields__ is deprecated; use @newfield instead.

      epydoc-3.0.1+dfsg/doc/manual-reference.html0000644000175000017500000005316610750103050021043 0ustar pronovicpronovic References

      References

      Command Line Usage

      Usage: epydoc.py [ACTION] [options] NAMES...

      NAMES...
      A list of the Python objects that should be documented. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages.
      options
      --config=FILE         A configuration file, specifying additional OPTIONS
                            and/or NAMES.  This option may be repeated.
      -o PATH, --output=PATH
                            The output directory.  If PATH does not exist, then it
                            will be created.
      -q, --quiet           Decrease the verbosity.
      -v, --verbose         Increase the verbosity.
      --debug               Show full tracebacks for internal errors.
      --simple-term         Do not try to use color or cursor control when
                            displaying the progress bar, warnings, or errors.
      
      Actions:
        --html              Write HTML output.
        --text              Write plaintext output. (not implemented yet)
        --latex             Write LaTeX output.
        --dvi               Write DVI output.
        --ps                Write Postscript output.
        --pdf               Write PDF output.
        --check             Check completeness of docs.
        --pickle            Write the documentation to a pickle file.
        --version           Show epydoc's version number and exit.
        -h, --help          Show this message and exit.  For help on specific
                            topics, use "--help TOPIC".  Use "--help topics" for a
                            list of available help topics
      
      Generation Options:
        --docformat=NAME    The default markup language for docstrings.  Defaults
                            to "epytext".
        --parse-only        Get all information from parsing (don't introspect)
        --introspect-only   Get all information from introspecting (don't parse)
        --exclude=PATTERN   Exclude modules whose dotted name matches the regular
                            expression PATTERN
        --exclude-introspect=PATTERN
                            Exclude introspection of modules whose dotted name
                            matches the regular expression PATTERN
        --exclude-parse=PATTERN
                            Exclude parsing of modules whose dotted name matches
                            the regular expression PATTERN
        --inheritance=STYLE
                            The format for showing inheritance objects.  STYLE
                            should be one of: grouped, listed, included.
        --show-private      Include private variables in the output. (default)
        --no-private        Do not include private variables in the output.
        --show-imports      List each module's imports.
        --no-imports        Do not list each module's imports. (default)
        --show-sourcecode   Include source code with syntax highlighting in the
                            HTML output. (default)
        --no-sourcecode     Do not include source code with syntax highlighting in
                            the HTML output.
        --include-log       Include a page with the process log (epydoc-log.html)
      
      Output Options:
        --name=NAME         The documented project's name (for the navigation
                            bar).
        --css=STYLESHEET    The CSS stylesheet.  STYLESHEET can be either a
                            builtin stylesheet or the name of a CSS file.
        --url=URL           The documented project's URL (for the navigation bar).
        --navlink=HTML      HTML code for a navigation link to place in the
                            navigation bar.
        --top=PAGE          The "top" page for the HTML documentation.  PAGE can
                            be a URL, the name of a module or class, or one of the
                            special names "trees.html", "indices.html", or
                            "help.html"
        --help-file=FILE    An alternate help file.  FILE should contain the body
                            of an HTML file -- navigation bars will be added to
                            it.
        --show-frames       Include frames in the HTML output. (default)
        --no-frames         Do not include frames in the HTML output.
        --separate-classes  When generating LaTeX or PDF output, list each class
                            in its own section, instead of listing them under
                            their containing module.
      
      API Linking Options:
        --external-api=NAME
                            Define a new API document.  A new interpreted text
                            role NAME will be added.
        --external-api-file=NAME:FILENAME
                            Use records in FILENAME to resolve objects in the API
                            named NAME.
        --external-api-root=NAME:STRING
                            Use STRING as prefix for the URL generated from the
                            API NAME.
      
      Graph Options:
        --graph=GRAPHTYPE   Include graphs of type GRAPHTYPE in the generated
                            output.  Graphs are generated using the Graphviz dot
                            executable.  If this executable is not on the path,
                            then use --dotpath to specify its location.  This
                            option may be repeated to include multiple graph types
                            in the output.  GRAPHTYPE should be one of: all,
                            classtree, callgraph, umlclasstree.
        --dotpath=PATH      The path to the Graphviz 'dot' executable.
        --graph-font=FONT   Specify the font used to generate Graphviz graphs.
                            (e.g., helvetica or times).
        --graph-font-size=SIZE
                            Specify the font size used to generate Graphviz
                            graphs, in points.
        --pstat=FILE        A pstat output file, to be used in generating call
                            graphs.
      
      Return Value Options:
        --fail-on-error     Return a non-zero exit status, indicating failure, if
                            any errors are encountered.
        --fail-on-warning   Return a non-zero exit status, indicating failure, if
                            any errors or warnings are encountered (not including
                            docstring warnings).
        --fail-on-docstring-warning
                            Return a non-zero exit status, indicating failure, if
                            any errors or warnings are encountered (including
                            docstring warnings).
      

      Sample Configuration File

      Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following example configuration file demonstrates the various options that you can set. Lines beginning with # or ; are treated as comments.

      [epydoc] # Epydoc section marker (required by ConfigParser)
      
      # The list of objects to document.  Objects can be named using
      # dotted names, module filenames, or package directory names.
      # Alases for this option include "objects" and "values".
      modules: sys, os.path, re
      
      # The type of output that should be generated.  Should be one
      # of: html, text, latex, dvi, ps, pdf.
      output: html
      
      # The path to the output directory.  May be relative or absolute.
      target: html/
      
      # An integer indicating how verbose epydoc should be.  The default
      # value is 0; negative values will supress warnings and errors;
      # positive values will give more verbose output.
      verbosity: 0
      
      # A boolean value indicating that Epydoc should show a tracaback
      # in case of unexpected error. By default don't show tracebacks
      debug: 0
      
      # If True, don't try to use colors or cursor control when doing
      # textual output. The default False assumes a rich text prompt
      simple-term: 0
      
      
      ### Generation options
      
      # The default markup language for docstrings, for modules that do
      # not define __docformat__.  Defaults to epytext.
      docformat: epytext
      
      # Whether or not parsing should be used to examine objects.
      parse: yes
      
      # Whether or not introspection should be used to examine objects.
      introspect: yes
      
      # Don't examine in any way the modules whose dotted name match this
      # regular expression pattern.
      #exclude
      
      # Don't perform introspection on the modules whose dotted name match this
      # regular expression pattern.
      #exclude-introspect
      
      # Don't perform parsing on the modules whose dotted name match this
      # regular expression pattern.
      #exclude-parse
      
      # The format for showing inheritance objects.
      # It should be one of: 'grouped', 'listed', 'included'.
      inheritance: listed
      
      # Whether or not to inclue private variables.  (Even if included,
      # private variables will be hidden by default.)
      private: yes
      
      # Whether or not to list each module's imports.
      imports: no
      
      # Whether or not to include syntax highlighted source code in
      # the output (HTML only).
      sourcecode: yes
      
      # Whether or not to includea a page with Epydoc log, containing
      # effective option at the time of generation and the reported logs.
      include-log: no
      
      
      ### Output options
      
      # The documented project's name.
      #name: Example
      
      # The CSS stylesheet for HTML output.  Can be the name of a builtin
      # stylesheet, or the name of a file.
      css: white
      
      # The documented project's URL.
      #url: http://some.project/
      
      # HTML code for the project link in the navigation bar.  If left
      # unspecified, the project link will be generated based on the
      # project's name and URL.
      #link: <a href="somewhere">My Cool Project</a>
      
      # The "top" page for the documentation.  Can be a URL, the name
      # of a module or class, or one of the special names "trees.html",
      # "indices.html", or "help.html"
      #top: os.path
      
      # An alternative help file.  The named file should contain the
      # body of an HTML file; navigation bars will be added to it.
      #help: my_helpfile.html
      
      # Whether or not to include a frames-based table of contents.
      frames: yes
      
      # Whether each class should be listed in its own section when
      # generating LaTeX or PDF output.
      separate-classes: no
      
      
      ### API linking options
      
      # Define a new API document.  A new interpreted text role
      # will be created
      #external-api: epydoc
      
      # Use the records in this file to resolve objects in the API named NAME.
      #external-api-file: epydoc:api-objects.txt
      
      # Use this URL prefix to configure the string returned for external API.
      #external-api-root: epydoc:http://epydoc.sourceforge.net/api
      
      
      ### Graph options
      
      # The list of graph types that should be automatically included
      # in the output.  Graphs are generated using the Graphviz "dot"
      # executable.  Graph types include: "classtree", "callgraph",
      # "umlclass".  Use "all" to include all graph types
      graph: all
      
      # The path to the Graphviz "dot" executable, used to generate
      # graphs.
      dotpath: /usr/local/bin/dot
      
      # The name of one or more pstat files (generated by the profile
      # or hotshot module).  These are used to generate call graphs.
      pstat: profile.out
      
      # Specify the font used to generate Graphviz graphs.
      # (e.g., helvetica or times).
      graph-font: Helvetica
      
      # Specify the font size used to generate Graphviz graphs.
      graph-font-size: 10
      
      
      ### Return value options
      
      # The condition upon which Epydoc should exit with a non-zero
      # exit status. Possible values are error, warning, docstring_warning
      #fail-on: error
      

      Warnings and Errors

      If epydoc encounters an error while processing a docstring, it issues a warning message that describes the error, and attempts to continue generating documentation. Errors related to epytext are divided into three categories:

      Epytext Warnings
      are caused by epytext docstrings that contain questionable or suspicious markup. Epytext warnings do not prevent the docstring in question from being parsed.
      Field Warnings
      are caused by epytext docstrings containing invalid fields. The contents of the invalid field are generally ignored.
      Epytext Errors
      are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring.

      The following sections list and describe the warning messages that epydoc can generate. They are intended as a reference resource, which you can search for more information and possible causes if you encounter an error and do not understand it. These descriptions are also available in the epydoc(1) man page.

      Epytext Warnings

      Possible mal-formatted field item.
      Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (:) is not included in the field tag.
      Possible heading typo.
      Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading.

      Field Warnings

      @param for unknown parameter param.
      A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      tag did not expect an argument.
      The field tag tag was used with an argument, but it does not take one.
      tag expected an argument.
      The field tag tag was used without an argument, but it requires one.
      @type for unknown parameter param.
      A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      @type for unknown variable var.
      A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name.
      Unknown field tag tag.
      A docstring contains a field with the unknown tag tag.
      Redefinition of field.
      Multiple field tags define the value of field in the same docstring, but field can only take a single value.

      Epytext Errors

      Bad link target.
      The target specified for an inline link contruction (L{...}) is not well-formed. Link targets must be valid Python identifiers.
      Bad uri target.
      The target specified for an inline uri contruction (U{...}) is not well-formed. This typically occurs if inline markup is nested inside the URI target.
      Fields must be at the top level.
      The list of fields (@param, etc.) is contained by some other block structure (such as a list or a section).
      Fields must be the final elements in an epytext string.
      The list of fields (@param, etc.) is not at the end of a docstring.
      Headings must occur at top level.
      The heading is contianed in some other block structure (such as a list).
      Improper doctest block indentation.
      The doctest block dedents past the indentation of its initial prompt line.
      Improper heading indentation.
      The heading for a section is not left-aligned with the paragraphs in the section that contains it.
      Improper paragraph indentation.
      The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext.
      Invalid escape.
      An unknown escape sequence was used with the inline escape construction (E{...}).
      Lists must be indented.
      An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet.
      Unbalanced '{'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unbalanced '}'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unknown inline markup tag.
      An unknown tag was used with the inline markup construction (x{...}).
      Wrong underline character for heading.
      The underline character used for this section heading does not indicate an appopriate section level. The '=' character should be used to underline sections; '-' for subsections; and '~' for subsubsections.
      epydoc-3.0.1+dfsg/doc/history.html0000644000175000017500000000650010750103047017327 0ustar pronovicpronovic Epydoc History

      Epydoc History

      I originally became interested in automatic API documentation extraction tools for Python in March 2002. At the time, there were several such tools available, including pydoc and HappyDoc. However, none were widely used. I joined the doc-sig mailing list, and started working with its members on creating standards for API documentation tools in Python.

      I created epydoc as a tool for exploring the issues involved in writing an automatic API documentation extraction tool. I also decided to use epydoc to document the Natural Language Toolkit, so that I would have a fairly large project with which to test out my system. The markup language and the output of epydoc have changed many times, and epydoc itself has undergone at least 3 complete rewrites. But eventually epydoc matured into a more stable system.

      Significant portions of epydoc were written for version 3.0. This has allowed me to increase epydoc's functionality in several significant ways. The most significant change has to do with the way that epydoc extracts documentation information about python modules. In previous versions, epydoc extracted information about each module by importing it, and using introspection to examine its contents. The new version of epydoc still supports introspection, but is also capable of extracting information about python modules by parsing their source code. Furthermore, the new version of epydoc can combine these two sources of information (introspection & parsing). This is important because each source has its own advantages and disadvantages with respect to the other.

      epydoc-3.0.1+dfsg/doc/epydoc.html0000644000175000017500000052277610750103050017125 0ustar pronovicpronovic Epydoc

      Epydoc

      Automatic API Documentation Generation for Python

      Author: Edward Loper
      Version: 3.0b1

      Abstract

      Epydoc is a tool for generating API documentation for Python modules, based on their docstrings. For an example of epydoc's output, see the API documentation for epydoc itself (html, pdf). A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in reStructuredText, Javadoc, and plaintext. For a more extensive example of epydoc's output, see the API documentation for Python 2.4.

      Contents

      1   Installing Epydoc

      1.1   Downloading Epydoc

      Epydoc can be downloaded from the SourceForge download page. Epydoc is available in five formats:

      • RPM (.noarch.rpm)
      • Windows installer (.win32.exe)
      • Source install (.tar.gz)
      • Source install (.zip)
      • Source RPM (.src.rpm)

      If you are installing on RedHat, I recommend that you use the RPM file. If you are installing on Windows, I recommended that you use the windows installer. Otherwise, you should use one of the source install files.

      1.2   Getting Epydoc from Subversion

      If you wish to keep up on the latest developments, you can get the latest version of epydoc from the subversion repository:

      [/home/edloper]$ svn co https://epydoc.svn.sourceforge.net/svnroot/epydoc/trunk/epydoc epydoc
      [/home/edloper]$ ls epydoc
      Makefile  doc  man  sandbox  src
      

      This will create a directory named epydoc containing the latest version of epydoc. The epydoc package itself is in epydoc/src/epydoc (so adding epydoc/src to your PYTHONPATH will let you use it). You should periodically update your copy of the subversion repository, to make sure you have all the latest changes:

      [/home/edloper/epydoc]$ svn up
      

      You can browse the subversion repository here.

      1.3   Installing from the RPM File

      1. Download the RPM file to a directory of your choice.

      2. Use rpm to install the new package.

        [/tmp]$ su
        Password:
        [/tmp]# rpm -i epydoc-3.0.1.noarch.rpm
        
      3. Once epydoc is installed, you can delete the RPM file.

        [/tmp]# rm epydoc-3.0.1.rpm
        

      1.4   Installing from the Windows Installer

      1. Download and run epydoc-3.0.1.win32.exe.
      2. Follow the on-screen instructions. Epydoc will be installed in the epydoc subdirectory of your Python installation directory (typically C:\Python24\).
      3. The Windows installer creates two scripts in the Scripts subdirectory of your Python installation directory: epydoc.pyw opens the graphical user interface, and epydoc.py calls the command line interface. If you'd like, you can create shortcuts from these scripts to more convenient locations (such as your desktop or start menu).
      4. Once epydoc is installed, you can delete epydoc-3.0.1.win32.exe.

      1.5   Installing from the Source Distribution (using make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.

        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use make install in the eydoc-3.0.1/ directory to install epydoc.

        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# make install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        
      3. If you'd like to keep a local copy of the documentation, then use make installdocs. By default, this will install the documentation to /usr/share/doc/ and the man pages to /usr/share/man/. If you would prefer to install documentation to different directories (such as /usr/lib/doc), then edit the MAN and DOC variables at the top of Makefile before running make installdocs.

        [/tmp/epydoc-3.0.1]# make installdocs
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.

        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      1.6   Installing from the Source Distribution (without make)

      1. Download an epydoc source distribution to a directory of your choice, and uncompress it.

        [/tmp]$ wget -q http://prdownloads.sourceforge.net/epydoc/epydoc-3.0.1.tar.gz
        [/tmp]$ gunzip epydoc-3.0.1.tar.gz
        [/tmp]$ tar -xvf epydoc-3.0.1.tar
        
      2. Use the setup.py script in the eydoc-3.0.1/ directory to install epydoc.

        [/tmp]$ cd epydoc-3.0.1/
        [/tmp/epydoc-3.0.1]$ su
        Password:
        [/tmp/epydoc-3.0.1]# python setup.py install
        running install
        running build
        [...]
        copying build/scripts/epydoc -> /usr/bin
        changing mode of /usr/bin/epydoc to 100775
        [/tmp/epydoc-3.0.1]# cd ..
        [/tmp]#
        
      3. If you'd like to keep a local copy of the documentation, then copy it to a permanant location, such as /usr/share/doc/. You may also want to copy the man pages to a permanant location, such as /usr/share/man/.

        [/tmp]# cp -r epydoc-3.0.1/doc/ /usr/share/doc/epydoc/
        [/tmp]# cp epydoc-3.0.1/man/* /usr/share/man/
        
      4. Once epydoc is installed, you can delete the installation directory and the source distribution file.

        [/tmp]# rm -r epydoc-3.0.1
        [/tmp]# rm epydoc-3.0.1.tar
        

      1.7   Installing on Debian

      Epydoc 2.1 is available as a testing debian package (python-epydoc). The epydoc documentation is also available as a package (epydoc-doc).

      2   Using Epydoc

      Epydoc provides two user interfaces:

      • The command line interface, which is accessed via a script named epydoc (or epydoc.py on Windows)
      • The graphical interface, which is accessed via a script named epydocgui (or epydoc.pyw on Windows).

      Epydoc can also be accessed programmatically; see epydoc's API documentation for more information.

      2.1   The Command Line Interface

      The epydoc script extracts API documentation for a set of Python objects, and writes it using a selected output format. Objects can be named using dotted names, module filenames, or package directory names. (On Windows, this script is named epydoc.py.)

      2.1.1   Command Line Usage (Abbreviated)

      epydoc [--html|--pdf] [-o DIR] [--parse-only|--introspect-only] [-v|-q]
             [--name NAME] [--url URL] [--docformat NAME] [--graph GRAPHTYPE]
             [--inheritance STYLE] [--config FILE] OBJECTS...
      
      OBJECTS...
      A list of the Python objects that should be documented. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages.
      --html Generate HTML output. (default)
      --pdf Generate Adobe Acrobat (PDF) output, using LaTeX.
      -o DIR, --output DIR, --target DIR
       The output directory.
      --parse-only, --introspect-only
       By default, epydoc will gather information about each Python object using two methods: parsing the object's source code; and importing the object and directly introspecting it. Epydoc combines the information obtained from these two methods to provide more complete and accurate documentation. However, if you wish, you can tell epydoc to use only one or the other of these methods. For example, if you are running epydoc on untrusted code, you should use the --parse-only option.
      -v, -q Increase (-v) or decrease (-q) the verbosity of the output. These options may be repeated to further increase or decrease verbosity. Docstring markup warnings are supressed unless -v is used at least once.
      --name NAME The documented project's name.
      --url URL The documented project's URL.
      --docformat NAME
       The markup language that should be used by default to process modules' docstrings. This is only used for modules that do not define the special __docformat__ variable; it is recommended that you explicitly specify __docformat__ in all your modules.
      --graph GRAPHTYPE
       

      Include graphs of type GRAPHTYPE in the generated output. Graphs are generated using the Graphviz dot executable. If this executable is not on the path, then use --dotpath to specify its location. This option may be repeated to include multiple graph types in the output. To include all graphs, use --graph all. The available graph types are:

      • classtree: displays each class's base classes and subclasses;
      • callgraph: displays the callers and callees of each function or method. These graphs are based on profiling information, which must be specified using the --pstate option.
      • umlclass: displays each class's base classes and subclasses, using UML style. Methods and attributes are listed in the classes where they are defined. If type information is available about attributes (via the @type field), then those types are displayed as separate classes, and the attributes are displayed as associations.
      --inheritance STYLE
       

      The format that should be used to display inherited methods, variables, and properties. Currently, three styles are supported. To see an example of each style, click on it:

      • grouped: Inherited objects are gathered into groups, based on which class they are inherited from.
      • listed: Inherited objects are listed in a short list at the end of the summary table.
      • included: Inherited objects are mixed in with non-inherited objects.
      --config FILE Read the given configuration file, which can contain both options and Python object names. This option may be used multiple times, if you wish to use multiple configuration files. See Configuration Files for more information.

      The complete list of command line options is available in the Command Line Usage section.

      2.1.2   Examples

      The following command will generate HTML documentation for the sys module, and write it to the directory sys_docs:

      [epydoc]$ epydoc --html sys -o sys_docs
      

      The following commands are used to produce the API documentation for epydoc itself. The first command writes html output to the directory html/api, using epydoc as the project name and http://epydoc.sourcforge.net as the project URL. The white CSS style is used; inheritance is displayed using the listed style; and all graphs are included in the output. The second command writes pdf output to the file api.pdf in the directory latex/api, using Epydoc as the project name.

      [epydoc]$ epydoc -v -o html/api --name epydoc --css white \
                       --url http://epydoc.sourceforge.net \
                       --inheritance listed --graph all src/epydoc
      [epydoc]$ epydoc -v -o latex/api --pdf --name "Epydoc" src/epydoc
      

      2.1.3   Configuration Files

      Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following is a simple example of a configuration file.

      [epydoc] # Epydoc section marker (required by ConfigParser)
      
      # Information about the project.
      name: My Cool Project
      url: http://cool.project/
      
      # The list of modules to document.  Modules can be named using
      # dotted names, module filenames, or package directory names.
      # This option may be repeated.
      modules: sys, os.path, re
      modules: my/project/driver.py
      
      # Write html output to the directory "apidocs"
      output: html
      target: apidocs/
      
      # Include all automatically generated graphs.  These graphs are
      # generated using Graphviz dot.
      graph: all
      dotpath: /usr/local/bin/dot
      

      A more complete example, including all of the supported options, is also available.

      2.2   The Graphical Interface

      Epydoc also includes a graphical interface, for systems where command line interfaces are not convenient (such as Windows). The graphical interface can be invoked with the epydocgui command, or with epydoc.pyw in the Scripts subdirectory of the Python installation directory under Windows. Currently, the graphical interface can only generate HTML output.

      epydoc_gui.png

      Use the Add box to specify what objects you wish to document. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages. Once you have added all of the modules that you wish to document, press the Start button. Epydoc's progress will be displayed on the progress bar.

      To customize the output, click on the Options arrow at the bottom of the window. This opens the options pane, which contains fields corresponding to each command line option.

      epydoc_guiconfig.png

      The epydoc graphical interface can save and load project files, which record the set of modules and the options that you have selected. Select File->Save to save the current modules and options to a project file; and File->Open to open a previously saved project file. (These project files do not currently use the same format as the configuration files used by the command line interface.)

      For more information, see the epydocgui(1) man page.

      2.3   Documentation Completeness Checks

      The epydoc script can be used to check the completeness of the reference documentation. In particular, it will check that every module, class, method, and function has a description; that every parameter has a description and a type; and that every variable has a type. If the -p option is used, then these checks are run on both public and private objects; otherwise, the checks are only run on public objects.

      epydoc --check [-p] MODULES...

      MODULES...
      A list of the modules that should be checked. Modules may be specified using either filenames (such as epydoc/epytext.py) or module names (such as os.path). The filename for a package is its __init__.py file.
      -p Run documentation completeness checks on private objects.

      For each object that fails a check, epydoc will print a warning. For example, some of the warnings generated when checking the completeness of the documentation for epydoc's private objects are:

      epydoc.html.HTML_Doc._dom_link_to_html........No docs
      epydoc.html.HTML_Doc._module..................No type
      epydoc.html.HTML_Doc._link_to_html.link.......No descr
      epydoc.html.HTML_Doc._author.return...........No type
      epydoc.html.HTML_Doc._author.authors..........No descr, No type
      epydoc.html.HTML_Doc._author.container........No descr, No type
      epydoc.html.HTML_Doc._base_tree.uid...........No descr, No type
      epydoc.html.HTML_Doc._base_tree.width.........No descr, No type
      epydoc.html.HTML_Doc._base_tree.postfix.......No descr, No type
      

      If you'd like more fine-grained control over what gets checked, or you would like to check other fields (such as the author or version), then you should use the DocChecker class directly.

      2.4   HTML Files

      Every Python module and class is documented in its own file. Index files, tree files, a help file, and a frames-based table of contents are also created. The following list describes each of the files generated by epydoc:

      index.html
      The standard entry point for the documentation. Normally, index.html is a copy of the frames file (frames.html). But if the --no-frames option is used, then index.html is a copy of the API documentation home page, which is normally the documentation page for the top-level package or module (or the trees page if there is no top-level package or module).
      module-module.html
      The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      class-class.html
      The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType.
      module-pysrc.html
      A page with the module colorized source code, with links back to the objects main documentation pages. The creation of the colorized source pages can be controlled using the options --show-sourcecode and --no-sourcecode.
      module-tree.html
      The documented module hierarchy.
      class-tree.html
      The documented classes hierarchy.
      identifier-index.html
      The index of all the identifiers found in the documented items.
      term-index.html
      The index of all the term definition found in the docstrings. Term definitions are created using the Indexed Terms markup.
      bug-index.html
      The index of all the known bug in the documented sources. Bugs are marked using the @bug tag.
      todo-index.html
      The index of all the to-do items in the documented sources. They are marked using the @todo tag.
      help.html
      The help page for the project. This page explains how to use and navigate the webpage produced by epydoc.
      epydoc-log.html
      A page with the log of the epydoc execution. It is available clicking on the timestamp below each page, if the documentation was created using the --include-log option. The page also contains the list of the options enabled when the documentation was created.
      api-objects.txt
      A text file containing each available item and the URL where it is documented. Each item takes a file line and it is separated by the URL by a tab charecter. Such file can be used to create external API links.
      redirect.html
      A page containing Javascript code that redirect the browser to the documentation page indicated by the accessed fragment. For example opening the page redirect.html#epydoc.apidoc.DottedName the browser will be redirected to the page epydoc.apidoc.DottedName-class.html.
      frames.html
      The main frames file. Two frames on the left side of the window contain a table of contents, and the main frame on the right side of the window contains API documentation pages.
      toc.html
      The top-level table of contents page. This page is displayed in the upper-left frame of frames.html, and provides links to the toc-everything.html and toc-module-module.html pages.
      toc-everything.html
      The table of contents for the entire project. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the project.
      toc-module-module.html
      The table of contents for a module. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
      epydoc.css
      The CSS stylesheet used to display all HTML pages.

      2.5   CSS Stylesheets

      Epydoc creates a CSS stylesheet (epydoc.css) when it builds the API documentation for a project. You can specify which stylesheet should be used using the --css command-line option. If you do not specify a stylesheet, and one is already present, epydoc will use that stylesheet; otherwise, it will use the default stylesheet.

      3   Python Docstrings

      Python documentation strings (or docstrings) provide a convenient way of associating documentation with Python modules, functions, classes, and methods. An object's docsting is defined by including a string constant as the first statement in the object's definition. For example, the following function defines a docstring:

      def x_intercept(m, b):
          """
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).
          """
          return -b/m

      Docstrings can be accessed from the interpreter and from Python programs using the "__doc__" attribute:

      >>> print x_intercept.__doc__
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).

      The pydoc module, which became part of the standard library in Python 2.1, can be used to display information about a Python object, including its docstring:

      >>> from pydoc import help
      
      >>> help(x_intercept)
      Help on function x_intercept in module __main__:
      
      x_intercept(m, b)
          Return the x intercept of the line y=m*x+b.  The x intercept of a
          line is the point at which it crosses the x axis (y=0).

      For more information about Python docstrings, see the Python Tutorial or the O'Reilly Network article Python Documentation Tips and Tricks.

      3.1   Variable docstrings

      Python don't support directly docstrings on variables: there is no attribute that can be attached to variables and retrieved interactively like the __doc__ attribute on modules, classes and functions.

      While the language doesn't directly provides for them, Epydoc supports variable docstrings: if a variable assignment statement is immediately followed by a bare string literal, then that assignment is treated as a docstring for that variable. In classes, variable assignments at the class definition level are considered class variables; and assignments to instance variables in the constructor (__init__) are considered instance variables:

      class A:
          x = 22
          """Docstring for class variable A.x"""
      
          def __init__(self, a):
              self.y = a
              """Docstring for instance variable A.y

      Variables may also be documented using comment docstrings. If a variable assignment is immediately preceeded by a comment whose lines begin with the special marker '#:', or is followed on the same line by such a comment, then it is treated as a docstring for that variable:

      #: docstring for x
      x = 22
      x = 22 #: docstring for x

      Notice that variable docstrings are only available for documentation when the source code is available for parsing: it is not possible to retrieve variable

      3.2   Items visibility

      Any Python object (modules, classes, functions, variables...) can be public or private. Usually the object name decides the object visibility: objects whose name starts with an underscore and doesn't end with an underscore are considered private. All the other objects (including the "magic functions" such as __add__) are public.

      For each module and class, Epydoc generates pages with both public and private methods. A Javascript snippet allows you to toggle the visibility of private objects.

      If a module wants to hide some of the objects it contains (either defined in the module itself or imported from other modules), it can explicitly list the names if its public names in the __all__ variable.

      If a module defines the __all__ variable, Epydoc uses its content to decide if the module objects are public or private.

      4   The Epytext Markup Language

      4.1   A Brief Introduction

      Epytext is a simple lightweight markup language that lets you add formatting and structue to docstrings. Epydoc uses that formatting and structure to produce nicely formatted API documentation. The following example (which has an unusually high ratio of documentaiton to code) illustrates some of the basic features of epytext:

      def x_intercept(m, b):
          """
          Return the x intercept of the line M{y=m*x+b}.  The X{x intercept}
          of a line is the point at which it crosses the x axis (M{y=0}).
      
          This function can be used in conjuction with L{z_transform} to
          find an arbitrary function's zeros.
      
          @type  m: number
          @param m: The slope of the line.
          @type  b: number
          @param b: The y intercept of the line.  The X{y intercept} of a
                    line is the point at which it crosses the y axis (M{x=0}).
          @rtype:   number
          @return:  the x intercept of the line M{y=m*x+b}.
          """
          return -b/m

      You can compare this function definition with the API documentation generated by epydoc. Note that:

      • Paragraphs are separated by blank lines.
      • Inline markup has the form "x{...}", where "x" is a single capital letter. This example uses inline markup to mark mathematical expressions ("M{...}"); terms that should be indexed ("X{...}"); and links to the documentation of other objects ("L{...}").
      • Descriptions of parameters, return values, and types are marked with "@field:" or "@field arg:", where "field" identifies the kind of description, and "arg" specifies what object is described.

      Epytext is intentionally very lightweight. If you wish to use a more expressive markup language, I recommend reStructuredText.

      4.2   Epytext Language Overview

      Epytext is a lightweight markup language for Python docstrings. The epytext markup language is used by epydoc to parse docstrings and create structured API documentation. Epytext markup is broken up into the following categories:

      • Block Structure divides the docstring into nested blocks of text, such as paragraphs and lists.

        o Basic Blocks are the basic unit of block structure.

        o Hierarchical blocks represent the nesting structure of the docstring.

      • Inline Markup marks regions of text within a basic block with properties, such as italics and hyperlinks.

      4.3   Block Structure

      Block structure is encoded using indentation, blank lines, and a handful of special character sequences.

      • Indentation is used to encode the nesting structure of hierarchical blocks. The indentation of a line is defined as the number of leading spaces on that line; and the indentation of a block is typically the indentation of its first line.
      • Blank lines are used to separate blocks. A blank line is a line that only contains whitespace.
      • Special character sequences are used to mark the beginnings of some blocks. For example, '-' is used as a bullet for unordered list items, and '>>>' is used to mark doctest blocks.

      The following sections describe how to use each type of block structure.

      4.3.1   Paragraphs

      A paragraph is the simplest type of basic block. It consists of one or more lines of text. Paragraphs must be left justified (i.e., every line must have the same indentation). The following example illustrates how paragraphs can be used:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.  Paragraphs can
          span multiple lines, and can contain
          I{inline markup}.
      
          This is another paragraph.  Paragraphs
          are separated by blank lines.
          """
          *[...]*

      This is a paragraph. Paragraphs can span multiple lines, and contain inline markup.

      This is another paragraph. Paragraphs are separated from each other by blank lines.

      4.3.2   Lists

      Epytext supports both ordered and unordered lists. A list consists of one or more consecutive list items of the same type (ordered or unordered), with the same indentation. Each list item is marked by a bullet. The bullet for unordered list items is a single dash character (-). Bullets for ordered list items consist of a series of numbers followed by periods, such as 12. or 1.2.8..

      List items typically consist of a bullet followed by a space and a single paragraph. The paragraph may be indented more than the list item's bullet; often, the paragraph is intended two or three characters, so that its left margin lines up with the right side of the bullet. The following example illustrates a simple ordered list.

      Docstring Input Rendered Output
      def example():
          """
          1. This is an ordered list item.
      
          2. This is a another ordered list
          item.
      
          3. This is a third list item.  Note that
             the paragraph may be indented more
             than the bullet.
          """
          *[...]*
      1. This is an ordered list item.
      2. This is another ordered list item.
      3. This is a third list item. Note that the paragraph may be indented more than the bullet.

      List items can contain more than one paragraph; and they can also contain sublists, literal blocks, and doctest blocks. All of the blocks contained by a list item must all have equal indentation, and that indentation must be greater than or equal to the indentation of the list item's bullet. If the first contained block is a paragraph, it may appear on the same line as the bullet, separated from the bullet by one or more spaces, as shown in the previous example. All other block types must follow on separate lines.

      Every list must be separated from surrounding blocks by indentation:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
            2. This a second list
               item.
                 - This is a sublist
          """
          [...]

      This is a paragraph.

      1. This is a list item.
      2. This is a second list item.
        • This is a sublist.

      Note that sublists must be separated from the blocks in their parent list item by indentation. In particular, the following docstring generates an error, since the sublist is not separated from the paragraph in its parent list item by indentation:

      Docstring Input Rendered Output
      def example():
          """
          1. This is a list item.  Its
          paragraph is indented 7 spaces.
          - This is a sublist.  It is
            indented 7 spaces.
          """
          #[...]
      L5: Error: Lists must be indented.

      The following example illustrates how lists can be used:

      Docstring Input Rendered Output
      def example():
          """
          This is a paragraph.
            1. This is a list item.
              - This is a sublist.
              - The sublist contains two
                items.
                  - The second item of the
                    sublist has its own sublist.
      
            2. This list item contains two
               paragraphs and a doctest block.
      
               >>> print 'This is a doctest block'
               This is a doctest block
      
               This is the second paragraph.
          """
          #[...]

      This is a paragraph.

      1. This is a list item.

        • This is a sublist.
        • The sublist contains two items.
          • The second item of the sublist has its own own sublist.
      2. This list item contains two paragraphs and a doctest block.

        >>> print 'This is a doctest block'
        This is a doctest block

        This is the second paragraph.

      Epytext will treat any line that begins with a bullet as a list item. If you want to include bullet-like text in a paragraph, then you must either ensure that it is not at the beginning of the line, or use escaping to prevent epytext from treating it as markup:

      Docstring Input Rendered Output
      def example():
          """
          This sentence ends with the number
          1.  Epytext can't tell if the "1."
          is a bullet or part of the paragraph,
          so it generates an error.
          """
          #[...]
      L4: Error: Lists must be indented.
      def example():
          """
          This sentence ends with the number 1.
      
          This sentence ends with the number
          E{1}.
          """
          #[...]

      This sentence ends with the number 1.

      This sentence ends with the number 1.

      4.3.3   Sections

      A section consists of a heading followed by one or more child blocks.

      • The heading is a single underlined line of text. Top-level section headings are underlined with the '=' character; subsection headings are underlined with the '-' character; and subsubsection headings are underlined with the '~' character. The length of the underline must exactly match the length of the heading.
      • The child blocks can be paragraphs, lists, literal blocks, doctest blocks, or sections. Each child must have equal indentation, and that indentation must be greater than or equal to the heading's indentation.

      The following example illustrates how sections can be used:

      Docstring Input Rendered Output
      def example():
          """
          This paragraph is not in any section.
      
          Section 1
          =========
            This is a paragraph in section 1.
      
            Section 1.1
            -----------
            This is a paragraph in section 1.1.
      
          Section 2
          =========
            This is a paragraph in section 2.
          """
          #[...]

      Section 1

      This is a paragraph in section 1.

      Section 1.1

      This is a paragraph in section 1.1.

      Section 2

      This is a paragraph in section 2.

      4.3.4   Literal Blocks

      Literal blocks are used to represent "preformatted" text. Everything within a literal block should be displayed exactly as it appears in plaintext. In particular:

      • Spaces and newlines are preserved.
      • Text is shown in a monospaced font.
      • Inline markup is not detected.

      Literal blocks are introduced by paragraphs ending in the special sequence "::". Literal blocks end at the first line whose indentation is equal to or less than that of the paragraph that introduces them. The following example shows how literal blocks can be used:

      Docstring Input Rendered Output
      def example():
          """
          The following is a literal block::
      
              Literal /
                     / Block
      
          This is a paragraph following the
          literal block.
          """
          #[...]

      The following is a literal block:

      Literal /
             / Block
      

      This is a paragraph following the literal block.

      Literal blocks are indented relative to the paragraphs that introduce them; for example, in the previous example, the word "Literal" is displayed with four leading spaces, not eight. Also, note that the double colon ("::") that introduces the literal block is rendered as a single colon.

      4.3.5   Doctest Blocks

      Doctest blocks contain examples consisting of Python expressions and their output. Doctest blocks can be used by the doctest module to test the documented object. Doctest blocks begin with the special sequence ">>>". Doctest blocks are delimited from surrounding blocks by blank lines. Doctest blocks may not contain blank lines. The following example shows how doctest blocks can be used:

      Docstring Input Rendered Output
      def example():
          """
          The following is a doctest block:
      
              >>> print (1+3,
              ...        3+5)
              (4, 8)
              >>> 'a-b-c-d-e'.split('-')
              ['a', 'b', 'c', 'd', 'e']
      
          This is a paragraph following the
          doctest block.
          """
          #[...]

      The following is a doctest block:

      >>> print (1+3,
      ...        3+5)
      (4, 8)
      >>> 'a-b-c-d-e'.split('-')
      ['a', 'b', 'c', 'd', 'e']

      This is a paragraph following the doctest block.

      4.3.6   Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field is marked by a field tag, which consist of an at sign ('@') followed by a field name, optionally followed by a space and a field argument, followed by a colon (':'). For example, '@return:' and '@param x:' are field tags.

      Fields can contain paragraphs, lists, literal blocks, and doctest blocks. All of the blocks contained by a field must all have equal indentation, and that indentation must be greater than or equal to the indentation of the field's tag. If the first contained block is a paragraph, it may appear on the same line as the field tag, separated from the field tag by one or more spaces. All other block types must follow on separate lines.

      Fields must be placed at the end of the docstring, after the description of the object. Fields may be included in any order.

      Fields do not need to be separated from other blocks by a blank line. Any line that begins with a field tag followed by a space or newline is considered a field.

      The following example illustrates how fields can be used:

      Docstring Input Rendered Output
      def example():
          """
          @param x: This is a description of
              the parameter x to a function.
              Note that the description is
              indented four spaces.
          @type x: This is a description of
              x's type.
          @return: This is a description of
              the function's return value.
      
              It contains two paragraphs.
          """
          #[...]
      Parameters:

      x - This is a description of the parameter x to a function. Note that the description is indented four spaces.

      (type=This is a description of x's type.)
      Returns:

      This is a description of the function's return value.

      It contains two paragraphs.

      For a list of the fields that are supported by epydoc, see the epydoc fields chapter.

      4.4   Inline Markup

      Inline markup has the form 'x{...}', where x is a single capital letter that specifies how the text between the braces should be rendered. Inline markup is recognized within paragraphs and section headings. It is not recognized within literal and doctest blocks. Inline markup can contain multiple words, and can span multiple lines. Inline markup may be nested.

      A matching pair of curly braces is only interpreted as inline markup if the left brace is immediately preceeded by a capital letter. So in most cases, you can use curly braces in your text without any form of escaping. However, you do need to escape curly braces when:

      1. You want to include a single (un-matched) curly brace.
      2. You want to preceed a matched pair of curly braces with a capital letter.

      Note that there is no valid Python expression where a pair of matched curly braces is immediately preceeded by a capital letter (except within string literals). In particular, you never need to escape braces when writing Python dictionaries. See also escaping.

      4.4.1   Basic Inline Markup

      Epytext defines four types of inline markup that specify how text should be displayed:
      • I{...}: Italicized text.
      • B{...}: Bold-faced text.
      • C{...}: Source code or a Python identifier.
      • M{...}: A mathematical expression.

      By default, source code is rendered in a fixed width font; and mathematical expressions are rendered in italics. But those defaults may be changed by modifying the CSS stylesheet. The following example illustrates how the four basic markup types can be used:

      Docstring Input Rendered Output
      def example():
          """
          I{B{Inline markup} may be nested; and
          it may span} multiple lines.
      
            - I{Italicized text}
            - B{Bold-faced text}
            - C{Source code}
            - M{Math}
      
          Without the capital letter, matching
          braces are not interpreted as markup:
          C{my_dict={1:2, 3:4}}.
          """
          #[...]

      Inline markup may be nested; and it may span multiple lines.

      • Italicized text
      • Bold-faced text
      • Source code
      • Math: m*x+b

      Without the capital letter, matching braces are not interpreted as markup: my_dict={1:2, 3:4}.

      4.4.2   URLs

      The inline markup construct U{text<url>} is used to create links to external URLs and URIs. 'text' is the text that should be displayed for the link, and 'url' is the target of the link. If you wish to use the URL as the text for the link, you can simply write "U{url}". Whitespace within URL targets is ignored. In particular, URL targets may be split over multiple lines. The following example illustrates how URLs can be used:

      Docstring Input Rendered Output
      def example():
          """
          - U{www.python.org}
          - U{http://www.python.org}
          - U{The epydoc homepage<http://
          epydoc.sourceforge.net>}
          - U{The B{Python} homepage
          <www.python.org>}
          - U{Edward Loper<mailto:edloper@
          gradient.cis.upenn.edu>}
          """
          #[...]

      4.4.4   Indexed Terms

      Epydoc automatically creates an index of term definitions for the API documentation. The inline markup construct 'X{...}' is used to mark terms for inclusion in the index. The term itself will be italicized; and a link will be created from the index page to the location of the term in the text. The following example illustrates how index terms can be used:

      Docstring Input Rendered Output
      def example():
          """
          An X{index term} is a term that
          should be included in the index.
          """
          #[...]

      An index term is a term that should be included in the index.

      Index
      index term example
      x intercept x_intercept
      y intercept x_intercept

      4.4.5   Symbols

      Symbols are used to insert special characters in your documentation. A symbol has the form 'S{code}', where code is a symbol code that specifies what character should be produced. The following example illustrates how symbols can be used to generate special characters:

      Docstring Input Rendered Output
      def example():
          """
          Symbols can be used in equations:
      
            - S{sum}S{alpha}/x S{<=} S{beta}
      
          S{<-} and S{larr} both give left
          arrows.  Some other arrows are
          S{rarr}, S{uarr}, and S{darr}.
          """
          #[...]

      Symbols can be used in equations:

      • ∑ α/x ≤ β

      ← and ← both give left arrows. Some other arrows are →, ↑, and ↓.

      Although symbols can be quite useful, you should keep in mind that they can make it harder to read your docstring in plaintext. In general, symbols should be used sparingly. For a complete list of the symbols that are currently supported, see the reference documentation for epytext.SYMBOLS.

      4.4.6   Escaping

      Escaping is used to write text that would otherwise be interpreted as epytext markup. Epytext was carefully constructed to minimize the need for this type of escaping; but sometimes, it is unavoidable. Escaped text has the form 'E{code}', where code is an escape code that specifies what character should be produced. If the escape code is a single character (other than '{' or '}'), then that character is produced. For example, to begin a paragraph with a dash (which would normally signal a list item), write 'E{-}'. In addition, two special escape codes are defined: 'E{lb}' produces a left curly brace ('{'); and 'E{rb}' produces a right curly brace ('}'). The following example illustrates how escaping can be used:

      Docstring Input Rendered Output
      def example():
          """
          This paragraph ends with two
          colons, but does not introduce
          a literal blockE{:}E{:}
      
          E{-} This is not a list item.
      
          Escapes can be used to write
          unmatched curly braces:
          E{rb}E{lb}
          """
          #[...]

      This paragraph ends with two colons, but does not introduce a literal block::

      - This is not a list item.

      Escapes can be used to write unmatched curly braces: }{

      4.4.7   Graphs

      The inline markup construct 'G{graphtype args...}' is used to insert automatically generated graphs. The following graphs generation constructions are currently defines:

      Markup Description
      G{classtree classes...} Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed.
      G{packagetree modules...} Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed.
      G{importgraph modules...} Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed.
      G{callgraph functions...} Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed.

      4.5   Characters

      4.5.1   Valid Characters

      Valid characters for an epytext docstring are space (\040); newline (\012); and any letter, digit, or punctuation, as defined by the current locale. Control characters (\000-\010` and ``\013-\037) are not valid content characters. Tabs (\011) are expanded to spaces, using the same algorithm used by the Python parser. Carridge-return/newline pairs (\015\012) are converted to newlines.

      4.5.2   Content Characters

      Characters in a docstring that are not involved in markup are called content characters. Content characters are always displayed as-is. In particular, HTML codes are not passed through. For example, consider the following example:

      Docstring Input Rendered Output
      def example():
          """
          <B>test</B>
          """
          #[...]
      <B>test</B>

      The docstring is rendered as <B>test</B>, and not as the word "test" in bold face.

      4.5.3   Spaces and Newlines

      In general, spaces and newlines within docstrings are treated as soft spaces. In other words, sequences of spaces and newlines (that do not contain a blank line) are rendered as a single space, and words may wrapped at spaces. However, within literal blocks and doctest blocks, spaces and newlines are preserved, and no word-wrapping occurs; and within URL targets and documentation link targets, whitespace is ignored.

      5   Epydoc Fields

      Fields are used to describe specific properties of a documented object. For example, fields can be used to define the parameters and return value of a function; the instance variables of a class; and the author of a module. Each field consists of a tag, an optional argument, and a body.

      • The tag is a case-insensitive word that indicates what kind of documentation is given by the field.
      • The optional argument specifies what object, parameter, or group is documented by the field.
      • The body contains the main contents of the field.

      5.1   Field Markup

      Each docstring markup langauge marks fields differently. The following table shows the basic fields syntax for each markup language. For more information, see the definition of field syntax for each markup language.

      Epytext reStructuredText Javadoc
      @tag: body...
      @tag arg: body...
      
      :tag: body...
      :tag arg: body...
      
      @tag body...
      @tag arg body...
      
      Definition of epytext fields Definition of ReStructuredText fields Definition of Javadoc fields

      5.2   Supported Fields

      The following table lists the fields that epydoc currently recognizes. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      5.2.1   Functions and Methods parameters

      @param p: ...
      A description of the parameter p for a function or method.
      @type p: ...
      The expected type for the parameter p.
      @return: ...
      The return value for a function or method.
      @rtype: ...
      The type of the return value for a function or method.
      @keyword p: ...
      A description of the keyword parameter p.
      @raise e: ...
      A description of the circumstances under which a function or method raises exception e.

      These tags can be used to specify attributes of parameters and return value of function and methods. These tags are usually put in the the docstring of the function to be documented.

      Note

      constructor parameters

      In C extension modules, extension classes cannot have a docstring attached to the __init__ function; consequently it is not possible to document parameters and exceptions raised by the class constructor. To overcome this shortcoming, the tags @param, @keyword, @type, @exception are also allowed to appear in the class docstring. In this case they refer to constructor parameters.

      @param fields should be used to document any explicit parameter (including the keyword parameter). @keyword fields should only be used for non-explicit keyword parameters:

      def plant(seed, *tools, **options):
          """
          @param seed: The seed that should be planted.
          @param tools: Tools that should be used to plant the seed.
          @param options: Any extra options for the planting.
      
          @keyword dig_deep: Plant the seed deep under ground.
          @keyword soak: Soak the seed before planting it.
          """
          #[...]

      Since the @type field allows for arbitrary text, it does not automatically create a crossreference link to the specified type, and is not written in fixed-width font by default. If you want to create a crossreference link to the type, or to write the type in a fixed-width font, then you must use inline markup:

      def ponder(person, time):
          """
          @param person: Who should think.
          @type person: L{Person} or L{Animal}
          @param time: How long they should think.
          @type time: C{int} or C{float}
          """
          #[...]

      5.2.2   Variables parameters

      @ivar v: ...
      A description of the class instance variable v.
      @cvar v: ...
      A description of the static class variable v.
      @var v: ...
      A description of the module variable v.
      @type v: ...
      The type of the variable v.

      These tags are usually put in a module or class docstring. If the sources can be parsed by Epydoc it is also possible to document the variable in their own docstrings: see variable docstrings

      Epydoc considers class variables the ones defined directly defined in the class body. A common Python idiom is to create instance variables settings their default value in the class instead of the constructor (hopefully if the default is immutable...).

      If you want to force Epydoc to classify as instance variable one whose default value is set at class level, you can describe it using the tag @ivar in the context of a variable docstring:

      class B:
          y = 42
          """@ivar: This is an instance variable."""

      5.2.3   Properties parameters

      @type: ...
      The type of the property.

      The @type tag can be attached toa property docstring to specify its type.

      5.2.4   Grouping and Sorting

      @group g: c1,...,cn
      Organizes a set of related children of a module or class into a group. g is the name of the group; and c1,...,cn are the names of the children in the group. To define multiple groups, use multiple group fields.
      @sort: c1,...,cn
      Specifies the sort order for the children of a module or class. c1,...,cn are the names of the children, in the order in which they should appear. Any children that are not included in this list will appear after the children from this list, in alphabetical order.

      These tags can be used to present groups of related items in a logical way. They apply to modules and classes docstrings.

      For the @group and @sort tags, asterisks (*) can be used to specify multiple children at once. An asterisk in a child name will match any substring:

      class widget(size, weight, age):
          """
          @group Tools: zip, zap, *_tool
          @group Accessors: get_*
          @sort: get_*, set_*, unpack_*, cut
          """
          #[...]

      Note

      group markers

      It is also possible to group set of related items enclosing them into special comment starting with the group markers '#{' and '#}' The group title can be specified after the opening group marker. Example:

      #{ Database access functions
      
      def read(id):
          #[...]
      
      def store(item):
          #[...]
      
      def delete(id):
          #[...]
      
      # groups can't be nested, so a closing marker is not required here.
      
      #{ Web publish functions
      
      def get(request):
          #[...]
      
      def post(request):
          #[...]
      
      #}

      5.2.5   Notes and Warnings

      @note: ...
      A note about an object. Multiple note fields may be used to list separate notes.
      @attention: ...
      An important note about an object. Multiple attention fields may be used to list separate notes.
      @bug: ...

      A description of a bug in an object. Multiple bug fields may be used to report separate bugs.

      Note

      If any @bug field is used, the HTML writer will generate a the page bug-index.html, containing links to all the items tagged with the field.

      @warning: ...
      A warning about an object. Multiple warning fields may be used to report separate warnings.

      5.2.6   Status

      @version: ...
      The current version of an object.
      @todo [ver]: ...

      A planned change to an object. If the optional argument ver is given, then it specifies the version for which the change will be made. Multiple todo fields may be used if multiple changes are planned.

      Note

      If any @todo field is used, the HTML writer will generate a the page todo-index.html, containing links to all the items tagged with the field.

      @deprecated: ...
      Indicates that an object is deprecated. The body of the field describe the reason why the object is deprecated.
      @since: ...
      The date or version when an object was first introduced.
      @status: ...
      The current status of an object.
      @change: ...
      A change log entry for this object.
      @permission: ...
      The object access permission, for systems such Zope/Plone supporting this concept. It may be used more than once to specify multiple permissions.

      5.2.7   Formal Conditions

      @requires: ...
      A requirement for using an object. Multiple requires fields may be used if an object has multiple requirements.
      @precondition: ...
      A condition that must be true before an object is used. Multiple precondition fields may be used if an object has multiple preconditions.
      @postcondition: ...
      A condition that is guaranteed to be true after an object is used. Multiple postcondition fields may be used if an object has multiple postconditions.
      @invariant: ...
      A condition which should always be true for an object. Multiple invariant fields may be used if an object has multiple invariants.

      5.2.8   Bibliographic Information

      @author: ...
      The author(s) of an object. Multiple author fields may be used if an object has multiple authors.
      @organization: ...
      The organization that created or maintains an object.
      @copyright: ...
      The copyright information for an object.
      @license: ...
      The licensing information for an object.
      @contact: ...
      Contact information for the author or maintainer of a module, class, function, or method. Multiple contact fields may be used if an object has multiple contacts.

      5.2.9   Other fields

      @summary: ...
      A summary description for an object. This description overrides the default summary (which is constructed from the first sentence of the object's description).
      @see: ...
      A description of a related topic. see fields typically use documentation crossreference links or external hyperlinks that link to the related topic.

      5.3   Fields synonyms

      Several fields have synonyms, or alternate tags. The following table lists all field synonyms. Field tags are written using epytext markup; if you are using a different markup language, then you should adjust the markup accordingly.

      Name Synonims
      @param p: ...
      @parameter p: ...
      @arg p: ...
      @argument p: ...
      @return: ... @returns: ...
      @rtype: ... @returntype: ...
      @raise e: ...
      @raises e: ...
      @except e: ...
      @exception e: ...
      @keyword p: ...
      @kwarg p: ...
      @kwparam p: ...
      @ivar v: ... @ivariable v: ...
      @cvar v: ... @cvariable v: ...
      @var v: ... @variable v: ...
      @see: ... @seealso: ...
      @warning: ... @warn: ...
      @requires: ...
      @require: ...
      @requirement: ...
      @precondition: ... @precond: ...
      @postcondition: ... @postcond: ...
      @organization: ... @org: ...
      @copyright: ... @(c): ...
      @change: ... @changed: ...

      5.4   Module metadata variables

      Some module variables are commonly used as module metadata. Epydoc can use the value provided by these variables as alternate form for tags. The following table lists the recognized variables and the tag they replace. Customized metadata variables can be added using the method described in Adding New Fields.

      Tag Variable
      @author __author__
      @authors __authors__
      @contact __contact__
      @copyright __copyright__
      @license __license__
      @deprecated __deprecated__
      @date __date__
      @version __version__

      5.5   Adding New Fields

      New fields can be defined for the docstrings in a module using the special @newfield tag (or its synonym, @deffield). This tag has the following syntax:

      @newfield tag: label [, plural ]
      

      Where tag is the new tag that's being defined; label is a string that will be used to mark this field in the generated output; and plural is the plural form of label, if different.

      New fields can be defined in any Python module. If they are defined in a package, it will be possible to use the newly defined tag from every package submodule.

      Each new field will also define a metadata variable which can be used to set the field value instead of the tag. For example, if a revision tag has been defined with:

      @newfield revision: Revision
      

      then it will be possible to set a value for the field using a module variable:

      __revision__ = "1234"

      The following example illustrates how the @newfield can be used: Docstring Input Rendered Output

      Docstring Input Rendered Output
      """
      @newfield corpus: Corpus, Corpora
      """
      
      def example():
          """
          @corpus: Bob's wordlist.
          @corpus: The British National Corpus.
          """
          [...]

      Corpora:

      • Bob's wordlist.
      • The British National Corpus.

      Note

      The module-level variable __extra_epydoc_fields__ is deprecated; use @newfield instead.

      6   Alternate Markup Languages

      Epydoc's default markup language is epytext, a lightweight markup language that's easy to write and to understand. But if epytext is not powerful enough for you, or doesn't suit your needs, epydoc also supports three alternate markup languages:

      reStructuredText
      is an "easy-to-read, what-you-see-is-what-you-get plaintext markup syntax". It is more powerful than epytext (e.g., it includes markup for tables and footnotes); but it is also more complex, and sometimes harder to read.
      Javadoc
      is a documentation markup language that was developed for Java. It consists of HTML, augmented by a set of special tagged fields.
      Plaintext docstrings
      are rendered verbatim (preserving whitespace).

      To specify the markup language for a module, you should define a module-level string variable __docformat__, containing the name of the module's markup language. The name of the markup language may optionally be followed by a language code (such as en for English). Conventionally, the definition of the __docformat__ variable immediately follows the module's docstring:

      # widget.py
      """
      Graphical support for `gizmos` and `widgets`.
      """
      __docformat__ = "restructuredtext en"
      #[...]

      To change the default markup language from the command line, use the --docformat option. For example, the following command generates API documentation for the existing regular expression package re, which uses plaintext markup:

      [epydoc]$ epydoc --docformat plaintext re
      

      6.1   reStructuredText

      reStructuredText is a markup language that was developed in conjunction with Docutils. In order to parse reStructuredText docstrings, Docutils 0.3 or higher must be installed. If Docutils is not installed, then reStructuredText docstrings will be rendered as plaintext. Docutils can be downloaded from the Docutils SourceForge page.

      6.1.1   Default role

      Epydoc replaces the Docutils' default interpreted text role with the creation of documentation crossreference links. If you want to create a crossreference link to the somemod.Example class, you can put backquotes around your test, typing:

      `somemod.Example`
      

      6.1.2   Consolidated Fields

      In addition to the standard set of fields, the reStructruedText parser also supports consolidated fields, which combine the documentation for several objects into a single field. For example, a single :Parameters: field is often used to describe all of the parameters for a function or method:

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
          - `size`: The size of the fox (in meters)
          - `weight`: The weight of the fox (in stones)
          - `age`: The age of the fox (in years)
          """
          #[...]

      Epydoc will automatically extract information about each parameter from this list. These consolidated fields may be written using either a bulleted list or a definition list.

      • If a consolidated field is written as a bulleted list, then each list item must begin with the field's argument, marked as interpreted text, and followed by a colon or dash.
      • If a consolidated field is written as a definition list, then each definition item's term should contain the field's argument, (it is not mandatory for it being marked as interpreted text).

      The term classifier, if present, is used to specify the associated type. The following example shows the use of a definition list to define a consolidated field (note that docutils requires a space before and after the ':' used to mark classifiers).

      def fox_speed(size, weight, age):
          """
          Return the maximum speed for a fox.
      
          :Parameters:
            size
              The size of the fox (in meters)
            weight : float
              The weight of the fox (in stones)
            age : int
              The age of the fox (in years)
          """
          #[...]

      The following consolidated fields are currently supported by epydoc:

      Consolidated Field Tag Corresponding Base Field Tag
      :Parameters: :param:
      :Exceptions: :except:
      :Groups: :group:
      :Keywords: :keyword:
      :Variables: :var:
      :IVariables: :ivar:
      :CVariables: :cvar:
      :Types: :type:

      6.1.3   Graph directives

      The epydoc reStructuredText reader defines several custom directives, which can be used to automatically generate a variety of graphs. The following custom directives are currently defined:

      Directive Description
      .. classtree:: [classes...]
          :dir: up|down|left|right
      
      Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down).
      .. packagetree:: [modules...]
          :dir: up|down|left|right
          :style: uml|tree
      
      Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down). The style option specifies whether packages should be displayed in a tree, or using nested UML symbols.
      .. importgraph:: [modules...]
          :dir: up|down|left|right
      
      Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed. The dir option specifies the orientation for the graph (default=left).
      .. callgraph:: [functions...]
          :dir: up|down|left|right
      
      Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed. The dir option specifies the orientation for the graph (default=right).
      .. dotgraph:: [title...]
          :caption: text...
          graph...
      
      Display a custom Graphviz dot graph. The body of the directive (graph...) should contain the body of a dot graph. The optional title argument, if specified, is used as the title of the graph. The optional caption option can be used to provide a caption for the graph.

      6.1.4   Colorized snippets directive

      Using reStructuredText markup it is possible to specify Python snippets in a doctest block. SUch block will be colorized as in epytext Doctest Blocks.

      >>> def double(x):
      ...     return x * 2
      ...
      >>> print double(8)
      16

      Doctest block are mostly useful to be run as a part of automatized test suite using the doctest module. If the Python prompt gets in your way when you try to copy and paste and you are not interested in self-testing docstrings, the python directive will let you obtain a simple block of colorized text:

      Docstring Input Rendered Output
      .. python::
      
          def fib(n):
              """Print a Fibonacci series."""
              a, b = 0, 1
              while b < n:
                  print b,
                  a, b = b, a+b
      
      def fib(n):
          """Print a Fibonacci series."""
          a, b = 0, 1
          while b < n:
              print b,
              a, b = b, a+b

      6.1.6   Indexed Terms in reStructuredText

      Epydoc uses indexed terms to create a table of terms definitions. Indexed terms are created using the epytext markup X{...}.

      If you want to create indexed terms in reStructuredText modules, you can use the term interpreted text role. For example:

      Docstring Input Rendered Output
      def example():
          """
          An :term:`index term` is a term that
          should be included in the index.
          """
          #[...]

      An index term is a term that should be included in the index.

      Index
      index term example
      x intercept x_intercept
      y intercept x_intercept

      6.2   Javadoc

      Javadoc is a markup language developed by Sun Microsystems for documenting Java APIs. The epydoc implementation of Javadoc is based on the Javadoc 1.4.2 reference documentation. However, there are likely to be some minor incompatibilities between Sun's implementation and epydoc's. Known incompatibilities include:

      • Epydoc does not support the Javadoc block tag @serial.
      • Epydoc does not support the following Javadoc inline tags: {@docroot}, {@inheritdoc}, {@value}.
      • Epydoc adds many field tags that Sun does not include, such as @var, @type, and @group.

      6.2.1   Javadoc Fields

      For compatibility with Javadoc, every @see field is assumed to contain a single crossreference link, unless its body is quoted, or it starts with an HTML tag. See the Javadoc reference manual for more information about how the @see field is encoded in Javadoc.

      Because Javadoc does not mark end of the optional argument, field arguments must contain exactly one word. Thus, multi-word arguments are not available in Javadoc. In particular, all group names must be single words.

      7   References

      7.1   Command Line Usage

      Usage: epydoc.py [ACTION] [options] NAMES...

      NAMES...
      A list of the Python objects that should be documented. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages.
      options
      --config=FILE         A configuration file, specifying additional OPTIONS
                            and/or NAMES.  This option may be repeated.
      -o PATH, --output=PATH
                            The output directory.  If PATH does not exist, then it
                            will be created.
      -q, --quiet           Decrease the verbosity.
      -v, --verbose         Increase the verbosity.
      --debug               Show full tracebacks for internal errors.
      --simple-term         Do not try to use color or cursor control when
                            displaying the progress bar, warnings, or errors.
      
      Actions:
        --html              Write HTML output.
        --text              Write plaintext output. (not implemented yet)
        --latex             Write LaTeX output.
        --dvi               Write DVI output.
        --ps                Write Postscript output.
        --pdf               Write PDF output.
        --check             Check completeness of docs.
        --pickle            Write the documentation to a pickle file.
        --version           Show epydoc's version number and exit.
        -h, --help          Show this message and exit.  For help on specific
                            topics, use "--help TOPIC".  Use "--help topics" for a
                            list of available help topics
      
      Generation Options:
        --docformat=NAME    The default markup language for docstrings.  Defaults
                            to "epytext".
        --parse-only        Get all information from parsing (don't introspect)
        --introspect-only   Get all information from introspecting (don't parse)
        --exclude=PATTERN   Exclude modules whose dotted name matches the regular
                            expression PATTERN
        --exclude-introspect=PATTERN
                            Exclude introspection of modules whose dotted name
                            matches the regular expression PATTERN
        --exclude-parse=PATTERN
                            Exclude parsing of modules whose dotted name matches
                            the regular expression PATTERN
        --inheritance=STYLE
                            The format for showing inheritance objects.  STYLE
                            should be one of: grouped, listed, included.
        --show-private      Include private variables in the output. (default)
        --no-private        Do not include private variables in the output.
        --show-imports      List each module's imports.
        --no-imports        Do not list each module's imports. (default)
        --show-sourcecode   Include source code with syntax highlighting in the
                            HTML output. (default)
        --no-sourcecode     Do not include source code with syntax highlighting in
                            the HTML output.
        --include-log       Include a page with the process log (epydoc-log.html)
      
      Output Options:
        --name=NAME         The documented project's name (for the navigation
                            bar).
        --css=STYLESHEET    The CSS stylesheet.  STYLESHEET can be either a
                            builtin stylesheet or the name of a CSS file.
        --url=URL           The documented project's URL (for the navigation bar).
        --navlink=HTML      HTML code for a navigation link to place in the
                            navigation bar.
        --top=PAGE          The "top" page for the HTML documentation.  PAGE can
                            be a URL, the name of a module or class, or one of the
                            special names "trees.html", "indices.html", or
                            "help.html"
        --help-file=FILE    An alternate help file.  FILE should contain the body
                            of an HTML file -- navigation bars will be added to
                            it.
        --show-frames       Include frames in the HTML output. (default)
        --no-frames         Do not include frames in the HTML output.
        --separate-classes  When generating LaTeX or PDF output, list each class
                            in its own section, instead of listing them under
                            their containing module.
      
      API Linking Options:
        --external-api=NAME
                            Define a new API document.  A new interpreted text
                            role NAME will be added.
        --external-api-file=NAME:FILENAME
                            Use records in FILENAME to resolve objects in the API
                            named NAME.
        --external-api-root=NAME:STRING
                            Use STRING as prefix for the URL generated from the
                            API NAME.
      
      Graph Options:
        --graph=GRAPHTYPE   Include graphs of type GRAPHTYPE in the generated
                            output.  Graphs are generated using the Graphviz dot
                            executable.  If this executable is not on the path,
                            then use --dotpath to specify its location.  This
                            option may be repeated to include multiple graph types
                            in the output.  GRAPHTYPE should be one of: all,
                            classtree, callgraph, umlclasstree.
        --dotpath=PATH      The path to the Graphviz 'dot' executable.
        --graph-font=FONT   Specify the font used to generate Graphviz graphs.
                            (e.g., helvetica or times).
        --graph-font-size=SIZE
                            Specify the font size used to generate Graphviz
                            graphs, in points.
        --pstat=FILE        A pstat output file, to be used in generating call
                            graphs.
      
      Return Value Options:
        --fail-on-error     Return a non-zero exit status, indicating failure, if
                            any errors are encountered.
        --fail-on-warning   Return a non-zero exit status, indicating failure, if
                            any errors or warnings are encountered (not including
                            docstring warnings).
        --fail-on-docstring-warning
                            Return a non-zero exit status, indicating failure, if
                            any errors or warnings are encountered (including
                            docstring warnings).
      

      7.2   Sample Configuration File

      Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following example configuration file demonstrates the various options that you can set. Lines beginning with # or ; are treated as comments.

      [epydoc] # Epydoc section marker (required by ConfigParser)
      
      # The list of objects to document.  Objects can be named using
      # dotted names, module filenames, or package directory names.
      # Alases for this option include "objects" and "values".
      modules: sys, os.path, re
      
      # The type of output that should be generated.  Should be one
      # of: html, text, latex, dvi, ps, pdf.
      output: html
      
      # The path to the output directory.  May be relative or absolute.
      target: html/
      
      # An integer indicating how verbose epydoc should be.  The default
      # value is 0; negative values will supress warnings and errors;
      # positive values will give more verbose output.
      verbosity: 0
      
      # A boolean value indicating that Epydoc should show a tracaback
      # in case of unexpected error. By default don't show tracebacks
      debug: 0
      
      # If True, don't try to use colors or cursor control when doing
      # textual output. The default False assumes a rich text prompt
      simple-term: 0
      
      
      ### Generation options
      
      # The default markup language for docstrings, for modules that do
      # not define __docformat__.  Defaults to epytext.
      docformat: epytext
      
      # Whether or not parsing should be used to examine objects.
      parse: yes
      
      # Whether or not introspection should be used to examine objects.
      introspect: yes
      
      # Don't examine in any way the modules whose dotted name match this
      # regular expression pattern.
      #exclude
      
      # Don't perform introspection on the modules whose dotted name match this
      # regular expression pattern.
      #exclude-introspect
      
      # Don't perform parsing on the modules whose dotted name match this
      # regular expression pattern.
      #exclude-parse
      
      # The format for showing inheritance objects.
      # It should be one of: 'grouped', 'listed', 'included'.
      inheritance: listed
      
      # Whether or not to inclue private variables.  (Even if included,
      # private variables will be hidden by default.)
      private: yes
      
      # Whether or not to list each module's imports.
      imports: no
      
      # Whether or not to include syntax highlighted source code in
      # the output (HTML only).
      sourcecode: yes
      
      # Whether or not to includea a page with Epydoc log, containing
      # effective option at the time of generation and the reported logs.
      include-log: no
      
      
      ### Output options
      
      # The documented project's name.
      #name: Example
      
      # The CSS stylesheet for HTML output.  Can be the name of a builtin
      # stylesheet, or the name of a file.
      css: white
      
      # The documented project's URL.
      #url: http://some.project/
      
      # HTML code for the project link in the navigation bar.  If left
      # unspecified, the project link will be generated based on the
      # project's name and URL.
      #link: <a href="somewhere">My Cool Project</a>
      
      # The "top" page for the documentation.  Can be a URL, the name
      # of a module or class, or one of the special names "trees.html",
      # "indices.html", or "help.html"
      #top: os.path
      
      # An alternative help file.  The named file should contain the
      # body of an HTML file; navigation bars will be added to it.
      #help: my_helpfile.html
      
      # Whether or not to include a frames-based table of contents.
      frames: yes
      
      # Whether each class should be listed in its own section when
      # generating LaTeX or PDF output.
      separate-classes: no
      
      
      ### API linking options
      
      # Define a new API document.  A new interpreted text role
      # will be created
      #external-api: epydoc
      
      # Use the records in this file to resolve objects in the API named NAME.
      #external-api-file: epydoc:api-objects.txt
      
      # Use this URL prefix to configure the string returned for external API.
      #external-api-root: epydoc:http://epydoc.sourceforge.net/api
      
      
      ### Graph options
      
      # The list of graph types that should be automatically included
      # in the output.  Graphs are generated using the Graphviz "dot"
      # executable.  Graph types include: "classtree", "callgraph",
      # "umlclass".  Use "all" to include all graph types
      graph: all
      
      # The path to the Graphviz "dot" executable, used to generate
      # graphs.
      dotpath: /usr/local/bin/dot
      
      # The name of one or more pstat files (generated by the profile
      # or hotshot module).  These are used to generate call graphs.
      pstat: profile.out
      
      # Specify the font used to generate Graphviz graphs.
      # (e.g., helvetica or times).
      graph-font: Helvetica
      
      # Specify the font size used to generate Graphviz graphs.
      graph-font-size: 10
      
      
      ### Return value options
      
      # The condition upon which Epydoc should exit with a non-zero
      # exit status. Possible values are error, warning, docstring_warning
      #fail-on: error
      

      7.3   Warnings and Errors

      If epydoc encounters an error while processing a docstring, it issues a warning message that describes the error, and attempts to continue generating documentation. Errors related to epytext are divided into three categories:

      Epytext Warnings
      are caused by epytext docstrings that contain questionable or suspicious markup. Epytext warnings do not prevent the docstring in question from being parsed.
      Field Warnings
      are caused by epytext docstrings containing invalid fields. The contents of the invalid field are generally ignored.
      Epytext Errors
      are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring.

      The following sections list and describe the warning messages that epydoc can generate. They are intended as a reference resource, which you can search for more information and possible causes if you encounter an error and do not understand it. These descriptions are also available in the epydoc(1) man page.

      7.3.1   Epytext Warnings

      Possible mal-formatted field item.
      Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (:) is not included in the field tag.
      Possible heading typo.
      Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading.

      7.3.2   Field Warnings

      @param for unknown parameter param.
      A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      tag did not expect an argument.
      The field tag tag was used with an argument, but it does not take one.
      tag expected an argument.
      The field tag tag was used without an argument, but it requires one.
      @type for unknown parameter param.
      A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
      @type for unknown variable var.
      A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name.
      Unknown field tag tag.
      A docstring contains a field with the unknown tag tag.
      Redefinition of field.
      Multiple field tags define the value of field in the same docstring, but field can only take a single value.

      7.3.3   Epytext Errors

      Bad link target.
      The target specified for an inline link contruction (L{...}) is not well-formed. Link targets must be valid Python identifiers.
      Bad uri target.
      The target specified for an inline uri contruction (U{...}) is not well-formed. This typically occurs if inline markup is nested inside the URI target.
      Fields must be at the top level.
      The list of fields (@param, etc.) is contained by some other block structure (such as a list or a section).
      Fields must be the final elements in an epytext string.
      The list of fields (@param, etc.) is not at the end of a docstring.
      Headings must occur at top level.
      The heading is contianed in some other block structure (such as a list).
      Improper doctest block indentation.
      The doctest block dedents past the indentation of its initial prompt line.
      Improper heading indentation.
      The heading for a section is not left-aligned with the paragraphs in the section that contains it.
      Improper paragraph indentation.
      The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext.
      Invalid escape.
      An unknown escape sequence was used with the inline escape construction (E{...}).
      Lists must be indented.
      An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet.
      Unbalanced '{'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unbalanced '}'.
      The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
      Unknown inline markup tag.
      An unknown tag was used with the inline markup construction (x{...}).
      Wrong underline character for heading.
      The underline character used for this section heading does not indicate an appopriate section level. The '=' character should be used to underline sections; '-' for subsections; and '~' for subsubsections.
      epydoc-3.0.1+dfsg/doc/pysrc.thumbnail.png0000644000175000017500000001743110750103050020567 0ustar pronovicpronovic‰PNG  IHDRmPœ~lr,tEXtCreation TimeWed 23 Aug 2006 17:54:25 -0500ÂÞ…tIMEÖ  Ï“ pHYsttÞfxgAMA± üapIDATxÚí|ùs×'n q6îƒoŠâa]¶HÙ’mùHìqeOR›”k¦¶RSù!³³[55Áü4Uó/lílÕþ°IfÖ»ñdw¼«x|d¬H²K$E" ’ ‰ûFFãÚÏë'DB´ã‰$ǯXÍ÷ïü¼ïݯ[þÞÿü_w—ï¾öú벇ÒúÚºJ¥òøT*e³ÙÂf³‰ëŠÈÈ;‹r™¼ÑY”Ë/^T*›­>EE³Õj•JE«ÕRÈåõ®¢¢Þhµ¨PÔë÷‹J…WÙAéã?ž>~\561žÉ禦§ëõú¥K—~{ã7p­Õë2¹â¿²æ²š­wÒùR¹":­F½Nƒb¦P.ñU‡ÕhŠÙB™C‘5-)Ë\¹jg FF ˜óE¾XìƒQ/9¾Xl½I¯C±ÀU ¥ŠÍ¬7t­–¬X®ä¹ŠÕ¬7Täx!WäYc12(–x![ä-&†¥ÅJ3ÁO¨80áL±Œ†V“ž11 ŠÞHQQëÁÐØ†Š fHQk3¤b-S(a9?yû‚×a9Ç{kkcªv¹Z­ž:u ìCû¦Z¥üO?|­F…ÕêÔ*`¢F£’ãf»¨VÉåE%è¢]T«±— Jy¿BRîAtj¥BÝYT)ÐâA?©PÑݪ:‹T9¸¨PÈ­W®§È ²)‚0OlÐGÆÀjÐ-B×2J ºÕlb;íãh0Âá02&“©³Æí{»ozæ½÷Þ{öÌ™}z¤zÀ ‚ðÝï~·MóŸÿ÷azæ`µÃ© éT;X(ÈrªGí@ ˜$µSàøB[í´d Gü¦gh±­gúªQ;(öÕÑ3©P Úa´þ½ó>'Û‡­gþã¿»(#z8¶p-–*R å¸Ò"Q;T±Ð"4…B®yPT£—®¢š†(ZT)%Ýr¿HóETÿÀ¢¤XHïí¢NC¤3-ÂZÁö+‰Ú©HŠE¡×©1O쮌˜5Ð3Z3öž(ôŒ\Ü[„ÌåÄ®hAòbe=z&™LŒ´ÚÎO—œúB2ûÉ,ö×$=EЩìiGŽã¶¶¶xžGÞçó¥ñ7©ºèñå—_>°Rµ\Ö }z™NÉ—‹2ËCÆV­VSQ­ì¹†j4ÔøªÓþ`²üæ7¿ž_ÏÏχBðŠäjµloa¡Q¯[ÒÛÛ½žÏ厽üòûï«ÂÆfËçk¦Rr—/+#ù'W®¨DQvútС¥ò¦^ï]_O³,S­Ökµ†Ýn0µ,«O$6ÇÐÐÐã†â+Âzfxx«ÕŠëØXsq‘ذô­~³^Wª‰”¸çp´‚Ay0¨jz½ÍXL±±!O& C]_Wêõ-AP¬­µ8AÔ”×k>{vøÆ0È Òq’Kû´§.¾öûý×ðŸ8A3ìÀ®¡ÔÞV::6­ŸQü{ƒ™þ4;Û|Ô@'Û¹¹¹á®þýs„¯ uÙ}ôY4ýéOzX·Éﶇœ8ߤû©‹¯Ÿ}öY/êÓÀ¨;’ð‡–ºøžµŒ(_ÁétÖàúÖ2lWØú³}Èîý`å®z S­‹:µf/—4ë  Örµ‚:6ƒ9œ{Ív½–i4ñBfndf'W)”9¾¸Ý<é?;¹P)µd-§ÑÎÄ<»Ig¨7±B•‹BùndÃe²¡¹Ód[Ø[CÒm&†q“\N¬‹˜U4Ÿv˜Øx!=éªÔª~«û·¡¯ÙÁ×…L¾™ŽŒ9ý•Z¯Ñ±zæ&Ôˆ¶Ñ0jm½Ù€¤b4Z´ÅOV×—ÀqŸô …ŒGX‘årù°Úb½–.aêuÂÝRjb¾RªòôÎ`1и SÖµ³Ã3W7aèÀ´„ézÕGÔ_K„! NN~¶uM¨a„>ÅF –ˆŠ#X»»¹ä·§çÁ+—V®<Ç]@ j'°Ã´í šC¼üÑì ó•aÉ$­Yó Í‘Ò‡*»ôÌ…  d`ýôiàc† ¢n³ ¸ ʇ¤Ã<°oØ=ÜÁÚÀM6ƒÃK  ©1êµ8j`µ2&X…€pÓÅC–¡7"a!Ëd¨ !Šš ‰:šÍÖlÒê‰Ånb·2ÜDCØäCvò "¶*òÆp7º9À:!F(Ž˜¤]BÀê²0¦f«9ækC€b§1(£Ö@\}Èñ“þ €ËêØc0&/뛺ôL>Ÿ‡Ñ“N§û4‚0Y æ9 ‘æmÄŸŒHz]›¡° ü!ƒ™Ù¬]âYä±`/¾V=;<ݽCNt’,f±ùøCÆeÞÅO¸Å׎ÏIØ™!š©#‹ ½½4qºÇ tz4™zµŽº<”„17€H߉LÃ1 {TÚDZR©Ü¾}Úfxxx`àà–Ø™Yý ²9µv Db5˜¿55iù*ijEg„œvXlìV& ÒÐhå~/þãg^þýoÿÉe´BVÿÏl‡S=ǼA†<øýÓ¯Â{‚ØMpÙ¿zí;»kÅJé¥cg~vãÒˆÝ È|'VLÃi gcP;3Ø«äþÉéW~³öy4Ÿœ™…ó÷—ÿ ü9 6cæù»ÑÐzj×÷@pÿ[ÿ‚Þï¯'vþò•>Ç}=v¦r·Ñhè¥ ãzò@±~pƒñà9€Å` aaÀLD©< ö„MŠÊà8Ø7¸…ØÚBÞµ‹P÷©l¶$‹J«R£ŒàA›#ÆE}FªW m¡è ¸ê-¨Œ_)¿cD"õàAk´´gØaäQ—d®‹$”\§"Cm1yºFÔ„_ :ÀMºÆ>öê˜8Ÿ~ú©Éd´Μ9sX³‚7O&à· …Ýuøl¬)9ü08ག@~Z€)ywyãΘ˯!'M”e±åe ñ ´snô™vÏhؾ¶7ÖF—×^L{µ÷“‚„Š©iÒ®ŒÔ©­iŸ‘*h0üQaJ+Ð:4YÄUîíÇ)xž·Ùl‚ ô×3;”Ü-@”ÀˆÁ—ÇÎÃj!!€t{k¢;XÙêz lBÀ}ë²éÍÐ-ø µÛürA'0ío(ñăÐwŸtÜ3‚ˆ°œ/N>‡;'Ÿmÿ iؾ"½>µë¶{ÛyVR~þéóâK]öãÏþsF£Õjß~ûíÃ0jp$ñpù7ñðýÔ§‡öSØ–G÷ú‡—ºìÇíím\¡¯aEÖà½Oî ûì“Cît¾”Ê•\6ÈRëÖX(U=¶½d®ÄWŒ6y½ÑD&š.xìæÇëµ´ÝЦÅZzpq#rr¯×iÐûg62áXÆm3ÓkÙbyvìцÛ’ºâáñxüÚµk›››‡ÕÆú‹åJ£ÑÔªÕUbû4~}uee“èŠÝDŽÖÙØMÂ@¹tmÅã°â{;‰åP”ã­ZuyaCFH3ž.Âä:u,Èrë;$|½Ï]º²lÔëÔ*e$‡‘ÛKä78_ }á8E“˜Šš.¿f½j4*\IäB¨Y­äÉá&ÍSbâ°t@œâ¿ø€S_¼xñ°f?ûÙå±1÷Ú¡Á‘×… ÇauÎÎÎF£%Üy÷Ýk33³™ÙÚJNLxÃáTµZ»pajv6ðè=Í©KϼõÖ[ÈPgæÀâr:Íù<Ï0‹EŠÃÍ_|QúI~çNøìÙ1“‰ã Øêõ†Õj´C1Y¾þj»ô ä£Ýn‡Ã“““Ö{º§¨›ÁÇ‹{˜ß,cu“Uwþâü˜è›©½X±N½}8¹UɇíM;1K‘çŠ(,ECçÇNÂY†¤õXìÄ3Si$‡’¸§B]Ä\-è¿^‹3¨0îò+ä X]Î|>ø…íX:Š˜¼:ˆ¥B™*åèsMø¨L#r˜3Ä7 Xô†)5È™bòzˆZ©†£¥R*©C‰Qàðt:9GÅz& J˜‡á(“b÷4s/¾Z<3x|½¯V¼¹½ò§ó´—KÎÌÀ‡…Ò_Š„>ÛºûW¯½³¸·^J®Þ˜ñ&¸ìŸÎ½™är).§•|8 ‚<®˜÷v: «^¬×wrñO×o?74ma Å Âþ[SóWCK€^ Ї[é·ºmžp6/¤oï_ŸšG?ëÉ] ¢—öŽ; {k˜s¶\Žn³ ÀÝÚYýË‹?\Š¬ãæ‡Á³¾±‚P±ûà\ Ã›áUÜ¡!Ë€Íí6Û‚ã—Ñ3GLyžc„í@’Øs•ì·{Xxù÷°@ÿáû=áµ#¦ôÌûï¿Ï²l,ûÑ~ôÈöÉ݃×6>pJ³þª¬î!»w)²aÕ›2åÂç;Al¬×â  ::K›°©›= ˆ2)àø¥ûìÒ3ð¯3™ÌüüüQZ:MÖÆNêÔš—‡`ғд…FÞì ä‘BNèÑi´BÞÙ,'”Ç]_[­Ý¥g Ôl6ÛçfLؽgÆe$=Øó“O ƒ÷xG¡¿N©‹¯?ûì³\.»ŽöãžØS–ºøúôiòL£ÿ¹½oÒiG!ì™ÄààîÃäA\.¯T`Ÿ4`cCÇ Zž•JE:Í;7‘N§Q¦èÇßÕé4ÉdÁ뵋¹\Ʋ†P(qæÌÈø¸çÓ{jR×{Ð<Ï÷‘µZcq1,½Ž)s8L<_½tiannk"Q@s‡¥ï,K•ë€ @g2%` Q!ŒôííÔ×G³Ù|üøñþµAqÇç]°õÍ:òz2|‰ó/ëyˆ±`´˜Ëb%UÎ~Õ?åÆÍ,_´éÍû£ªîoüú摌<`Ù¬²™ŠŒ:÷ãfäðg]„%pôµu6¡õüJïô¾ ­ F«R=VÝ¥g®\¹•m±X^xá…k+òq/9‹ÿFâÝhhÊ;"—Éy±²›MÌÌbNpÂkËÑй‘gt:•^¯EžÏéÀ$_«Â‰ü`õ3“V?;0¶ÛòYœ>Ö±“MÐÇÐð5 <7h÷N{FVã[;ÙX¡R>;< ,àÒ`P¸+çFŸsúÿËå÷F+±MF­ƒ›´›KÀ,%/&VJó#3ŸÜ»õgçÞº¾½ ã_¥Tm¥£÷ÛÓçör‰X1ƒíÇ@I.;7<ÎÆˆ©[*€Ç†í¾!›÷_×o×5ò°oð8öòÅŽçà}Ò¾?S.—éË\¢(Òç×ýýУdZ`1ÂÇ´°<êÃMxŠÈÜ‹‡'=C9xFÞá£~®R¡€Õ‰šô (î¹ô(Ù˜žýË%ÂDZ¤§-à_[t˜úpœY^:÷"yÊF`o/_áDQ(KoÞ6áTë"ÿüóGlŸ>É7GSÚiG€ríÚ5HI–eçæ~—Wë‘Hž2t‘F£r:Í·oo¿ñÆÉv`âŸÿùsNæFGÝÉdÎÕª··“óó33_Û ®¬ç<®Çãéór!M·nm’C´õ&èÂä”§t€¢‹åXÖjD2µZ#“á x€f<žÿCÁÑh4;v¬mÐàÙWȹ=xNpHEX0ŒA£V9÷uÈO~òšŒ¼\™,VJÓ¾QzS:íZ…ã˜+sÔÃé|Ö™hÈFe£Iøt†è ®5áÕAѩȷðöƒQ`´Â}¤ïÛôŒ¸›MÀZP~EÁÖÞç\4NñꫯÖæ7ùº‚JMâ‘ÐI?yfÍUyx„§“XüqÏ0&—*宄Ùè;so~¾\ކÎÏÐ7Vc[×·—O ŒÃ6‚9ùQð&¼Æ ×àFr×a´ÀoÛÉÆ]&+*wz™4ŽÙ~m5ÍÂì£^ŒùÂ8 8…ÇÁÒ’žñÇ&ƒm!.áØ(ä êŸ8y./žuQ(ÓWb…Ôf:ÍâoÄîÕÐsöž£Yx’SWœâ(öc¡Tª5·Ý AFcP`žóþôy,¸›fÚind¶³hþž»?ié=Âüñ|`m±VÿÛÿúßyó¬Ù¨c´÷'&Y)q~—ó OZêÕ3p®ûœÛƒ‰ó×öz&_jƒøM¢ißz‚žpT*•’}¸mæéÑo¾"×›ºôÌÍ›75Éd}Ü{ÊR—žyçwŽÒ†+ jµ²}>¼X4ÅvªŠ5­æ¨‡óhe(1ô£=Âaò/Ôùï!ué™_ýêWN§ ~Øû…FóïþÛ¥Wž›<÷ÌH¥*^[Ú*IßYö9X^a;æ¹ PsÓé<[¥Rºm¦l‘/ñ£ÓÄRŸ“5t»‰œQ¯MdŠN+‰WÅúÅç&/ßÙp±ÈWª5txáÔØíà.¬k4A#¶FÞÀhP‡|)´Eža赚S“ÙyïÒ3Ô¿k÷ið­sSv³AɉPÈJŸSn·K•*(Ôï²æ9¸ÏèÔÖ˜+òô‹¨»¹ }b7a©› º|‰‡Özfb ^'O€®ó³ä…:¸G{É܈Ï_Åe3Ñï/´òÚ+‚8p¥óäYëv4#—‘°>^e=þŒÇãQ«Õ}Þç"ç)n“龫0=z?pЪ5‡G‰-m12X*½i·ÈnÇU²Ù’Z­r³&d¸bÙï·ó•a—Íjíµ{€2Í>š™ñ8Zö¸|GQýë_JØ=íøMOÅú‡.éÁHU±X1´¯½öÌ'Ÿ,¯¯Ç&'}år•¾*sòäP³Y]]]=þüæfâêÕuQ¬}ûÛ'ÿá® þÇ/£æØ˜ûûß?ÒÕ§"íã œ¾÷Ñß/´ÛM«R½^k&Ãýã?^ñùl33@ :­Vkf3¡V›ÍF?‚šóóãø™7ß4`Uú±ï Ñ ÑÁé®6Ê$üÓ"‘ ¸çv# ï{=±óêñ³ÒçP²©ÝI÷ИÓ_É+þ±ùjF½YŸp îæÉ]òé« þ(æƒ_O&1.Ú:Œìv&†™uzNà1.9¥aŒZF.—Ãåw™¬ùJ‰~‰ºö {kV½9[.h”j®Ê£g´ÊñVTªò*¥Êi´VëâN6n ßÑr$’d¨BëÑHduy…+qŸßºë‡a£žDP¶77É㤯ŷµ5 ùT™ËîF·u\sµ²¢P(‚±­·O½²šñ¶\0± ñ_vmÜ[KíDZ¬‡¼£!—+J²,VbÒéë ò¥…D1£R("æh¼¬3º¹#6j;™X©\¼IUýÀà–ö6žžWwb«ñíF³¡õÝÜÞ5ë ¬ërðº¶ØX‰oBõc¸åXÈn`YÆÈne"€ÆO¾Ü¢RK¥%Az, ,rÅÍ{=t{‰ qI-³\‘(‘ÕÂÙ†u(å m«Å×sKé=l-öXLQ-ºaM¦ÿ·Ë¢ gP¨IEND®B`‚epydoc-3.0.1+dfsg/doc/uml.thumbnail.png0000644000175000017500000000732710750103050020227 0ustar pronovicpronovic‰PNG  IHDR>PÎ]Q9,tEXtCreation TimeWed 23 Aug 2006 17:49:14 -0500J†¢tIMEÖ wX²© pHYsttÞfxgAMA± üa.IDATxÚÕ[[sÛÆ]Woà]´¨»dIqœÆuÒ:íLâéL’æ©/ùi¦oyhfò4I§umÉv,˲,‘I‘/ Á @="U¾H¤LJlwdy ì‚g¿ý¾óÝ…¨¿þå«Å¥%òÿSò•îvª©72ÌÜÂ|YwµtÖ0ÍÐ'-Œ>éê„åOu2H¿ß#Eៃ:¹¨uË‚«Žñ€3ÅÀÓ¨~¯ºÃü.Êú*c-)ð~wÍÑè*ƒK™ª°›ë—Ë ë÷ÙÙŸÏ×ëÿø–ˆnâ ‰7@¦¨~¿ïÞ=<Ëi—(ºb±X¿O¾ùŠxeC­“OþDzoo_Qj¨t:Z29]­5ÔF£×ë}·ÛeY6ˆ¸%w4 µµ¹±qP£å€¯®vÜ"šc6Œf[<ð|×™Ãæ8Â2F¹BÜnÂó¤×ÕÓ™ôLrÆ $•JɾkÓ¬T*.—‹ã8I’Ž Ï¾WUU§àtÐMÓÚ®[tâz³ÙÄcu½›Œ:åO—èBzô:ϲ¶ÒÇþ=Uºó«Ù{Òñˆ·Vo}øî5‰wdw¦öŸA ‘yôˆøýîÞ-{Å‘™­ûß.£\“ž<ù±gAèðòòÚÊÚ(3+l<-T«u—Àu:½nW…U9Æ¥÷~¦iõwnÜ84<Ùt5b¹ô¬B¬[#úÅyVÿÛ÷=êUD?Íò‡UåD.á»t8]vÒ›¦Õ‹Åb©TŠÇãn¸!¨x½^LÜ«P(ÀŠ¡PèñãÇ7oÞ$6øKƒÇøÃïnØ!OSåpt{ÆB2d›ŽgéL©oU-_Og2°ôƒ}ˆ¼h4Šþ_~ù%S­VÉdž‡ö¨c _|ñÅåAXörÚ‹’£|°aB_^Y±CÓ¦½^fYC×5†aດUmĬɅ+{y-]:v˜ï¿çêu³NM‘Z áLÖÖÈÊŠó4JÆá¾T ;Ú úÇOÍ… eñ7¡rÉŒ1þb2à±ÕÏ/ÅÜZ­ ÿän¯§i:Îs}ѬdѹEIäìâq¶¢¾IC/?ߎ2ÃûÎ^ºP®²,’ËùÎÂìð}õnW …hìœ6NޏŽ#Á1z«£¥R‚iBÑô®Í9P;½~—xŽÅüµu]rš‘-{$üœtÇ0†‡Ž“Œa†ÎÐŽRµ|¢ ´5ÍsM;ÍŒÊдÒl13œ“çêÍ–“ç“Ñðˆ¸/ZCGVRj³Ý¡÷‘RŸ Ép›üQÅïqÃsÍ67‰$5zßÒdP—,ÃÀmàú¸‚1ô üOà6¸[®)Õz# W˜¹“|€ ÜàÖ.žOD‚Ã@7ø î9AűŒ aÐѰ&¸2Üd«Ã؇å MÓÀŠ0z‘Í<žF«ÃÛòø° ‰Ö›KÄ¿ØÇkfpKëvÁ9¥š2 Ï'‎òîÒœƒ¢ôn.þþÊ"±T/®äË¿äž u,086èõ‹àà]€^®7"fƒŸŒÕbc{«DdG,Oaç¥é©üQî1>ØÞOIJţV§ƒ{Šª‚…AMh†úúüÌd ÃÀ¿^]‚åú&p‹1Ùëð¢x0/’½°äë}›íÎe€ºÚjÿûÞ¦Gtµ5eèZ£y{méñn uEmÎME1žr­nî%ä£wWO¯B\?ðù—]t ¿yç:üF7×½žÛéD> x%¸><¾RoØ.ÑÑ4 "ðWA‘CГ½4ÐëÛŘGj'“Eà#\åYêÀT2:XN&þ' ƒé¦Í$ot{}8:<»£ëpžxP±Øüȳ¿I|ºŸ¶úràGŒj1!5µ‰‚º<(Axâè †è}¯(ŽS~YnÐŽ@)ªk!¯6TfK1|Æä£¤{TS·®6?X_±Áú`IÌÒ0Ì ‡–ÍN}1˜Ïk5мnLcbŒƒ'¦‹0B¦ji8Sïäͬ‰È `›L`T½¦ Ž!iÀ8èRVꕦK" bQaÎ…¥Ð×É“‹n †ß¹±j¯àé'¸±AGùúÇ’±²WàcD-ŒÚjaö§‘§JeHÈd,|ú$uˆ6»~Z‡aEûf(Vª3ô?~xKm·š˜e$Bä\DNÅt³ÖÉ@_e€ at¤(¥JÍÌáæÆFKéRUÁ2 +£ÀñnÑÕ︆.ϯþ||˜ jö¿go.õƒ¬+¦Ù‹-íhƒx¼¾±AL]#ø¹`Ù+UCñkbø÷•ÆtJûZÑKÅM† Ó³J«Õª¤Ó/]i·A¦ðªV3[[Õz=àõ¾ÒËÁqÑ™™ C¯ÕjQU=Mˆ›ÛÛ?çr^·»X­*ß}‡%_†¢î~ðÁéýŒl­F&Ù|/—í€ik§@t¹Vçæ`õéXÌåÈSÅÊK' Me?i4èUWU,#Ëe(r•½^Ô×v3xÎõ¹9¿çUL¬sÌIC7º7"ËX2a #¿ÆÃfzúäöí±à;§ŒÊ0íN'_*aˆˆ´6²±2R¯&³Ž ö†K@#躮Y?:ÃÆööY] KåŽ}T‡Áúßf@€6³­])·ËuV 2ŸÏ#9G"‘QäèÐáÜp›û::ô:•e\‚­( âõõ.Ï[ïõ£ÑèÄ <Ñi†±Eö­ ±ÙDÏ?4uJ’„Ìà}-g]ôgÏ2‡‡á@€X‡ œB¹\©×o­®žÓWÅò—ýœ—p. úíµµßÞ¸a¿”+•àâ‹ÉdUQ›»Ì âAàù®µŒ°÷¸O  ooo#án³ÙœŸŸ_^^¾"è›Ïž!YJ.xf?›5wêdx´³—Õ`H’(â÷Q­–ŒÅž¥Rw~ÿû“î²,¯­­V!–]Õç‰÷–—‘JAçAŸOöù@8<ˆüþ7’Ìúü|¡ÿËiàr‚ö-÷àG…¾ŸË!‚Llr©?ÝÛƒ£ÃÀo„Ž6'B T*ƒÁ·þêQ¡GƒAð#"Þ ?.U«½÷Þ€>†Q(àß‚ ŒòBÓÎÖš­VUƒ×;ƒÔBswÿ³Ï>;ÿå‘K†n Ÿ$• †Tt>ŸˆDÀ6¢ ØÇf’äv‹Ç@=~ÿŸOEê„ [4¬Yûo¤’(¼Ù+I±PèþÖ–½M‡ ‰†Bòqê8-C–Q帥V¯Cµ£zÁo #“Ïo½x‘¬ÌÌ8-FOår Ññ*ÊQ}DÚ¶ß•B¼NG£HO3¸eÇîâô4†džX\dgë* ƒË‰Ðo¯¯§òùƒB¡R«Ý¹yÓw¼>ŠÀ€—p7÷öå—e|¼¿» o‘ƒÁ€,+ºÞªÕNZÚùÒN–êËZ`2ЦkŸ~ʼööh¹ætVG¼‹Eô±€z»Ý†`rX¯–t­žµËÌZ¯e@‹#Éã:Ø›ªªf2¿ßoüÇÝ|g¤\¬jµšÍf*ÐßN§Ó~M ;ÖË@ìv»íA¢Ž^ñx< M úææ&¢ó†õâ;”êë €ûÁƒׯ_· oùá‡>ÿüóÑ_únv¿Mô“³;«««?gwP÷sR,øªÃIÆ×ß}³´jêoóý/k·òÞ°|…VW‰vÿéCš¡á*-ÕœýçÅ”¦é3 ³œþ W¹{÷îOé‡ÿÜÚ@c†eµ~ççƒç3‹sªu²puлzwviÞþsXP ëØˆå¹~ýÌÓqîâúJW×­eV”µvÏÛmÃB_ MkºþÆ[®ó¬^ëòœ ôe:q…ÏÜç¸0ôa¤…Ëér‰ðÌ'xÜÒ…Ú_:Øàê±Þ®œþãz>Ÿ‡øC²é‚¡Á¾2ÝZ:à7¨ZE,Æ@`:ÜRÑ‹p6g•š•öñ„X,†:Ú$ d< ¯iü~ff&`m{Œ¥XRÅó‡5KÏRÛø>p‚ O2Ò  ã.’(àÚ 80]èh·\ŸÏçõzíaäh†`I< õ±ü}J·ÏÔ;ŽfÇ‚;ÙWï2f9<ÖC¥£óÓÃC#ØÝy~á?K˜h9(uõ&)îþÜN~æ›,[IEND®B`‚epydoc-3.0.1+dfsg/doc/epytextintro.html0000644000175000017500000000716410750103047020413 0ustar pronovicpronovic A Brief Introduction to Epytext

      A Brief Introduction to Epytext

      Epytext is a simple lightweight markup language that lets you add formatting and structure to docstrings. Epydoc uses that formatting and structure to produce nicely formatted API documentation. The following example (which has an unusually high ratio of documentaiton to code) illustrates some of the basic features of epytext:

      def x_intercept(m, b):
          """
          Return the x intercept of the line M{y=m*x+b}.  The X{x intercept}
          of a line is the point at which it crosses the x axis (M{y=0}).
      
          This function can be used in conjuction with L{z_transform} to
          find an arbitrary function's zeros.
      
          @type  m: number
          @param m: The slope of the line.
          @type  b: number
          @param b: The y intercept of the line.  The X{y intercept} of a
                    line is the point at which it crosses the y axis (M{x=0}).
          @rtype:   number
          @return:  the x intercept of the line M{y=m*x+b}.
          """
          return -b/m
      

      You can compare this function definition with the API documentation generated by epydoc. Note that:

      • Paragraphs are separated by blank lines.
      • Inline markup has the form "x{...}", where "x" is a single capital letter. This example uses inline markup to mark mathematical expressions ("M{...}"); terms that should be indexed ("X{...}"); and links to the documentation of other objects ("L{...}").
      • Descriptions of parameters, return values, and types are marked with "@field:" or "@field arg:", where "field" identifies the kind of description, and "arg" specifies what object is described.

      For more information about the epytext markup language, see the epytext manual. Epytext is intentionally very lightweight. If you wish to use a more expressive markup language, I recommend reStructuredText.

      epydoc-3.0.1+dfsg/doc/api/0002755000175000017500000000000010750103105015505 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html-module.html0000644000175000017500000003632710750103050024115 0ustar pronovicpronovic epydoc.docwriter.html
      Package epydoc :: Package docwriter :: Module html
      [hide private]
      [frames] | no frames]

      Module html

      source code

      The HTML output generator for epydoc. The main interface provided by this module is the HTMLWriter class.


      To Do: Add a cache to HTMLWriter.url()?

      Classes [hide private]
        HTMLWriter
        _HTMLDocstringLinker
      Functions [hide private]
       
      compile_template(docstring, template_string, output_function='out', debug=True)
      Given a template string containing inline python source code, return a python function that will fill in the template, and output the result.
      source code
      call graph 
       
      strip_indent(s)
      Given a multiline string s, find the minimum indentation for all non-blank lines, and return a new string formed by stripping that amount of indentation from all lines in s.
      source code
      call graph 
      Function Details [hide private]

      compile_template(docstring, template_string, output_function='out', debug=True)

      source code 
      call graph 

      Given a template string containing inline python source code, return a python function that will fill in the template, and output the result. The signature for this function is taken from the first line of docstring. Output is generated by making repeated calls to the output function with the given name (which is typically one of the function's parameters).

      The templating language used by this function passes through all text as-is, with three exceptions:

      • If every line in the template string is indented by at least x spaces, then the first x spaces are stripped from each line.
      • Any line that begins with '>>>' (with no indentation) should contain python code, and will be inserted as-is into the template-filling function. If the line begins a control block (such as 'if' or 'for'), then the control block will be closed by the first '>>>'-marked line whose indentation is less than or equal to the line's own indentation (including lines that only contain comments.)
      • In any other line, any expression between two '$' signs will be evaluated and inserted into the line (using str() to convert the result to a string).

      Here is a simple example:

      >>> TEMPLATE = '''
      ... <book>
      ...   <title>$book.title$</title>
      ...   <pages>$book.count_pages()$</pages>
      ... >>> for chapter in book.chapters:
      ...     <chaptername>$chapter.name$</chaptername>
      ... >>> #endfor
      ... </book>
      >>> write_book = compile_template('write_book(out, book)', TEMPLATE)

      Acknowledgements: The syntax used by compile_template is loosely based on Cheetah.


      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html._HTMLDocstringLinker-class.html0000644000175000017500000006245510750103050027662 0ustar pronovicpronovic epydoc.docwriter.html._HTMLDocstringLinker
      Package epydoc :: Package docwriter :: Module html :: Class _HTMLDocstringLinker
      [hide private]
      [frames] | no frames]

      Class _HTMLDocstringLinker

      source code


      Instance Methods [hide private]
       
      __init__(self, htmlwriter, container) source code
      call graph 
      string
      translate_indexterm(self, indexterm)
      Translate an index term to the appropriate output format.
      source code
      call graph 
      string
      translate_identifier_xref(self, identifier, label=None)
      Translate a crossreference link to a Python identifier to the appropriate output format.
      source code
      call graph 
       
      url_for(self, identifier) source code
      call graph 
       
      _failed_xref(self, identifier)
      Add an identifier to the htmlwriter's failed crossreference list.
      source code
      call graph 
      Method Details [hide private]

      translate_indexterm(self, indexterm)

      source code 
      call graph 

      Translate an index term to the appropriate output format. The output will typically include a crossreference anchor.

      Parameters:
      • indexterm - The index term to translate.
      Returns: string
      The translated index term.
      Overrides: markup.DocstringLinker.translate_indexterm
      (inherited documentation)

      translate_identifier_xref(self, identifier, label=None)

      source code 
      call graph 

      Translate a crossreference link to a Python identifier to the appropriate output format. The output will typically include a reference or pointer to the crossreference target.

      Parameters:
      • identifier - The name of the Python identifier that should be linked to.
      • label - The label that should be used for the identifier, if it's different from the name of the identifier.
      Returns: string
      The translated crossreference link.
      Overrides: markup.DocstringLinker.translate_identifier_xref
      (inherited documentation)

      epydoc-3.0.1+dfsg/doc/api/epydoc.cli.HTMLLogger-class.html0000644000175000017500000006250210750103050023434 0ustar pronovicpronovic epydoc.cli.HTMLLogger
      Package epydoc :: Module cli :: Class HTMLLogger
      [hide private]
      [frames] | no frames]

      Class HTMLLogger

      source code


      A logger used to generate a log of all warnings and messages to an HTML file.

      Instance Methods [hide private]
       
      __init__(self, directory, options) source code
       
      write_options(self, options) source code
       
      start_block(self, header)
      Start a new message block.
      source code
       
      end_block(self)
      End a warning block.
      source code
       
      log(self, level, message)
      Display a message.
      source code
       
      _message(self, level, message) source code
       
      close(self)
      Perform any tasks needed to close this logger.
      source code
       
      _elapsed_time(self) source code

      Inherited from log.Logger: end_progress, progress, start_progress

      Class Variables [hide private]
        FILENAME = 'epydoc-log.html'
        HEADER = '<?xml version="1.0" encoding="ascii"?>\n<!DOCTYPE ht...
        START_BLOCK = '<div class="log-block"><h2 class="log-hdr">%s</...
        MESSAGE = '<div class="log-%s"><b>%s</b>: \n%s</div>\n'
        END_BLOCK = '</div>'
        FOOTER = '</body>\n</html>\n'
      Method Details [hide private]

      start_block(self, header)

      source code 

      Start a new message block. Any calls to info(), warning(), or error() that occur between a call to start_block and a corresponding call to end_block will be grouped together, and displayed with a common header. start_block can be called multiple times (to form nested blocks), but every call to start_block must be balanced by a call to end_block.

      Overrides: log.Logger.start_block
      (inherited documentation)

      end_block(self)

      source code 

      End a warning block. See start_block for details.

      Overrides: log.Logger.end_block
      (inherited documentation)

      log(self, level, message)

      source code 

      Display a message.

      Parameters:
      • message - The message string to display. message may contain newlines, but does not need to end in a newline.
      • level - An integer value indicating the severity of the message.
      Overrides: log.Logger.log
      (inherited documentation)

      close(self)

      source code 

      Perform any tasks needed to close this logger.

      Overrides: log.Logger.close
      (inherited documentation)

      Class Variable Details [hide private]

      HEADER

      Value:
      '''<?xml version="1.0" encoding="ascii"?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                "DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
      <head>
        <title>Epydoc Log</title>
        <link rel="stylesheet" href="epydoc.css" type="text/css" />
      </head>
      ...
      

      START_BLOCK

      Value:
      '<div class="log-block"><h2 class="log-hdr">%s</h2>'
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr.ColorizedPyvalRepr-class.html0000644000175000017500000004435410750103050030246 0ustar pronovicpronovic epydoc.markup.pyval_repr.ColorizedPyvalRepr
      Package epydoc :: Package markup :: Module pyval_repr :: Class ColorizedPyvalRepr
      [hide private]
      [frames] | no frames]

      Class ColorizedPyvalRepr

      source code


      Instance Methods [hide private]
       
      __init__(self, tree, score, is_complete) source code
      call graph 

      Inherited from epytext.ParsedEpytextDocstring: __str__, index_terms, split_fields, summary, to_html, to_latex, to_plaintext

      Inherited from ParsedDocstring: __add__, concatenate

      Class Variables [hide private]

      Inherited from epytext.ParsedEpytextDocstring: SYMBOL_TO_HTML, SYMBOL_TO_LATEX

      Inherited from epytext.ParsedEpytextDocstring (private): _SUMMARY_RE

      Instance Variables [hide private]
        is_complete
      True if this colorized repr completely describes the object.
        score
      A score, evaluating how good this repr is.
      Method Details [hide private]

      __init__(self, tree, score, is_complete)
      (Constructor)

      source code 
      call graph 
      Overrides: epytext.ParsedEpytextDocstring.__init__

      epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.APIDoc-class.html0000644000175000017500000023127110750103050023260 0ustar pronovicpronovic epydoc.apidoc.APIDoc
      Package epydoc :: Module apidoc :: Class APIDoc
      [hide private]
      [frames] | no frames]

      Class APIDoc

      source code


      API documentation information for a single element of a Python program. APIDoc itself is an abstract base class; subclasses are used to specify what information should be recorded about each type of program element. In particular, APIDoc has two direct subclasses, VariableDoc for documenting variables and ValueDoc for documenting values; and the ValueDoc class is subclassed further for different value types.

      Each APIDoc subclass specifies the set of attributes that should be used to record information about the corresponding program element type. The default value for each attribute is stored in the class; these default values can then be overridden with instance variables. Most attributes use the special value UNKNOWN as their default value, to indicate that the correct value for that attribute has not yet been determined. This makes it easier to merge two APIDoc objects that are documenting the same element (in particular, to merge information about an element that was derived from parsing with information that was derived from introspection).

      For all attributes with boolean values, use only the constants True and False to designate true and false. In particular, do not use other values that evaluate as true or false, such as 2 or (). This restriction makes it easier to handle UNKNOWN values. For example, to test if a boolean attribute is True or UNKNOWN, use 'attrib in (True, UNKNOWN)' or 'attrib is not False'.

      Two APIDoc objects describing the same object can be merged, using the method merge_and_overwrite(other). After two APIDocs are merged, any changes to one will be reflected in the other. This is accomplished by setting the two APIDoc objects to use a shared instance dictionary. See the documentation for merge_and_overwrite for more information, and some important caveats about hashing.

      Instance Methods [hide private]
       
      __init__(self, **kwargs)
      Construct a new APIDoc object.
      source code
      call graph 
       
      _debug_setattr(self, attr, val)
      Modify an APIDoc's attribute.
      source code
       
      __setattr__(self, attr, val)
      Modify an APIDoc's attribute.
      source code
       
      __repr__(self)
      repr(x)
      source code
       
      pp(self, doublespace=0, depth=5, exclude=(), include=())
      Return a pretty-printed string representation for the information contained in this APIDoc.
      source code
       
      __str__(self, doublespace=0, depth=5, exclude=(), include=())
      Return a pretty-printed string representation for the information contained in this APIDoc.
      source code
       
      specialize_to(self, cls)
      Change self's class to cls.
      source code
      call graph 
       
      __hash__(self)
      hash(x)
      source code
      call graph 
       
      __cmp__(self, other) source code
      call graph 
      bool
      is_detailed(self)
      Does this object deserve a box with extra details?
      source code
      call graph 
       
      merge_and_overwrite(self, other, ignore_hash_conflict=False)
      Combine self and other into a merged object, such that any changes made to one will affect the other.
      source code
      call graph 
       
      apidoc_links(self, **filters)
      Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
      source code

      Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

      Class Variables [hide private]
        __has_been_hashed = False
      True iff self.__hash__() has ever been called.
        __mergeset = None
      The set of all APIDoc objects that have been merged with this APIDoc (using merge_and_overwrite()).
      Instance Variables [hide private]
          Docstrings
      string or None docstring = _Sentinel('UNKNOWN')
      The documented item's docstring.
      int docstring_lineno = _Sentinel('UNKNOWN')
      The line number on which the documented item's docstring begins.
          Information Extracted from Docstrings
      ParsedDocstring descr = _Sentinel('UNKNOWN')
      A description of the documented item, extracted from its docstring.
      ParsedDocstring summary = _Sentinel('UNKNOWN')
      A summary description of the documented item, extracted from its docstring.
      bool other_docs = _Sentinel('UNKNOWN')
      A flag indicating if the entire docstring body (except tags if any) is entirely included in the summary.
      (str, str, ParsedDocstring) metadata = _Sentinel('UNKNOWN')
      Metadata about the documented item, extracted from fields in its docstring.
      DocstringField extra_docstring_fields = _Sentinel('UNKNOWN')
      A list of new docstring fields tags that are defined by the documented item's docstring.
          Source Information
      str docs_extracted_by = _Sentinel('UNKNOWN')
      Information about where the information contained by this APIDoc came from.
      Properties [hide private]

      Inherited from object: __class__

      Method Details [hide private]

      __init__(self, **kwargs)
      (Constructor)

      source code 
      call graph 

      Construct a new APIDoc object. Keyword arguments may be used to initialize the new APIDoc's attributes.

      Raises:
      • TypeError - If a keyword argument is specified that does not correspond to a valid attribute for this (sub)class of APIDoc.
      Overrides: object.__init__

      _debug_setattr(self, attr, val)

      source code 

      Modify an APIDoc's attribute. This is used when epydoc.DEBUG is true, to make sure we don't accidentally set any inappropriate attributes on APIDoc objects.

      Raises:
      • AttributeError - If attr is not a valid attribute for this (sub)class of APIDoc. (attr is considered a valid attribute iff self.__class__ defines an attribute with that name.)

      __setattr__(self, attr, val)

      source code 

      Modify an APIDoc's attribute. This is used when epydoc.DEBUG is true, to make sure we don't accidentally set any inappropriate attributes on APIDoc objects.

      Raises:
      • AttributeError - If attr is not a valid attribute for this (sub)class of APIDoc. (attr is considered a valid attribute iff self.__class__ defines an attribute with that name.)
      Overrides: object.__setattr__

      __repr__(self)
      (Representation operator)

      source code 
      repr(x)
      
      
      Overrides: object.__repr__
      (inherited documentation)

      __str__(self, doublespace=0, depth=5, exclude=(), include=())
      (Informal representation operator)

      source code 

      Return a pretty-printed string representation for the information contained in this APIDoc.

      Overrides: object.__str__

      specialize_to(self, cls)

      source code 
      call graph 

      Change self's class to cls. cls must be a subclass of self's current class. For example, if a generic ValueDoc was created for a value, and it is determined that the value is a routine, you can update its class with:

      >>> valdoc.specialize_to(RoutineDoc)

      __hash__(self)
      (Hashing function)

      source code 
      call graph 
      hash(x)
      
      
      Overrides: object.__hash__
      (inherited documentation)

      is_detailed(self)

      source code 
      call graph 

      Does this object deserve a box with extra details?

      Returns: bool
      True if the object needs extra details, else False.

      merge_and_overwrite(self, other, ignore_hash_conflict=False)

      source code 
      call graph 

      Combine self and other into a merged object, such that any changes made to one will affect the other. Any attributes that other had before merging will be discarded. This is accomplished by copying self.__dict__ over other.__dict__ and self.__class__ over other.__class__.

      Care must be taken with this method, since it modifies the hash value of other. To help avoid the problems that this can cause, merge_and_overwrite will raise an exception if other has ever been hashed, unless ignore_hash_conflict is True. Note that adding other to a dictionary, set, or similar data structure will implicitly cause it to be hashed. If you do set ignore_hash_conflict to True, then any existing data structures that rely on other's hash staying constant may become corrupted.

      Returns:
      self
      Raises:
      • ValueError - If other has ever been hashed.

      apidoc_links(self, **filters)

      source code 

      Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

      Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

      • imports: Imported variables.
      • packages: Containing packages for modules.
      • submodules: Contained submodules for packages.
      • bases: Bases for classes.
      • subclasses: Subclasses for classes.
      • variables: All variables.
      • private: Private variables.
      • overrides: Points from class variables to the variables they override. This filter is False by default.

      Class Variable Details [hide private]

      __mergeset

      The set of all APIDoc objects that have been merged with this APIDoc (using merge_and_overwrite()). Each APIDoc in this set shares a common instance dictionary (__dict__).

      Value:
      None
      

      Instance Variable Details [hide private]

      metadata

      Metadata about the documented item, extracted from fields in its docstring. Currently this is encoded as a list of tuples (field, arg, descr). But that may change.
      Type:
      (str, str, ParsedDocstring)
      Value:
      _Sentinel('UNKNOWN')
      

      extra_docstring_fields

      A list of new docstring fields tags that are defined by the documented item's docstring. These new field tags can be used by this item or by any item it contains.
      Type:
      DocstringField
      Value:
      _Sentinel('UNKNOWN')
      

      docs_extracted_by

      Information about where the information contained by this APIDoc came from. Can be one of 'parser', 'introspector', or 'both'.
      Type:
      str
      Value:
      _Sentinel('UNKNOWN')
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.plaintext-module.html0000644000175000017500000001227610750103050025156 0ustar pronovicpronovic epydoc.docwriter.plaintext
      Package epydoc :: Package docwriter :: Module plaintext
      [hide private]
      [frames] | no frames]

      Module plaintext

      source code

      Plaintext output generation.

      Classes [hide private]
        PlaintextWriter
      epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.javadoc-module.html0000644000175000017500000000237010750103050024627 0ustar pronovicpronovic javadoc

      Module javadoc


      Classes

      ParsedJavadocDocstring

      Functions

      parse_docstring

      [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docintrospecter-module.html0000644000175000017500000027546210750103050024364 0ustar pronovicpronovic epydoc.docintrospecter
      Package epydoc :: Module docintrospecter
      [hide private]
      [frames] | no frames]

      Module docintrospecter

      source code

      Extract API documentation about python objects by directly introspecting their values.

      The function introspect_docs(), which provides the main interface of this module, examines a Python objects via introspection, and uses the information it finds to create an APIDoc objects containing the API documentation for that objects.

      The register_introspecter() method can be used to extend the functionality of docintrospector, by providing methods that handle special value types.

      Classes [hide private]
        _DevNull
      A "file-like" object that discards anything that is written and always reports end-of-file when read.
      Functions [hide private]
       
      clear_cache()
      Discard any cached APIDoc values that have been computed for introspected values.
      source code
       
      introspect_docs(value=None, name=None, filename=None, context=None, is_script=False, module_name=None)
      Generate the API documentation for a specified object by introspecting Python values, and return it as a ValueDoc.
      source code
      call graph 
       
      _get_valuedoc(value)
      If a ValueDoc for the given value exists in the valuedoc cache, then return it; otherwise, create a new ValueDoc, add it to the cache, and return it.
      source code
      call graph 
       
      introspect_module(module, module_doc, module_name=None, preliminary=False)
      Add API documentation information about the module module to module_doc.
      source code
      call graph 
       
      introspect_class(cls, class_doc, module_name=None)
      Add API documentation information about the class cls to class_doc.
      source code
      call graph 
       
      introspect_routine(routine, routine_doc, module_name=None)
      Add API documentation information about the function routine to routine_doc (specializing it to Routine_doc).
      source code
      call graph 
       
      introspect_property(prop, prop_doc, module_name=None)
      Add API documentation information about the property prop to prop_doc (specializing it to PropertyDoc).
      source code
      call graph 
       
      introspect_other(val, val_doc, module_name=None)
      Specialize val_doc to a GenericValueDoc and return it.
      source code
      call graph 
       
      isclass(object)
      Return true if the given object is a class.
      source code
      call graph 
       
      register_class_type(typ)
      Add a type to the lists of types that should be treated as classes.
      source code
       
      is_future_feature(object)
      Return True if object results from a from __future__ import feature statement.
      source code
      call graph 
      unicode
      get_docstring(value, module_name=None)
      Return the docstring for the given value; or None if it does not have a docstring.
      source code
      call graph 
      DottedName or UNKNOWN
      get_canonical_name(value, strict=False)
      Returns: the canonical name for value, or UNKNOWN if no canonical name can be found.
      source code
      call graph 
       
      verify_name(value, dotted_name)
      Verify the name.
      source code
      call graph 
       
      value_repr(value) source code
      DottedName
      get_containing_module(value)
      Return the name of the module containing the given value, or None if the module name can't be determined.
      source code
      call graph 
      module
      _find_function_module(func)
      Returns: The module that defines the given function.
      source code
      call graph 
       
      register_introspecter(applicability_test, introspecter, priority=10)
      Register an introspecter function.
      source code
       
      _get_introspecter(value) source code
      call graph 
       
      is_classmethod(v) source code
       
      is_staticmethod(v) source code
       
      is_property(v) source code
      call graph 
       
      is_getset(v) source code
      call graph 
       
      is_member(v) source code
      call graph 
       
      get_value_from_filename(filename, context=None) source code
      call graph 
       
      get_value_from_scriptname(filename) source code
       
      get_value_from_name(name, globs=None)
      Given a name, return the corresponding value.
      source code
       
      _lookup(module, name) source code
       
      _import(name, filename=None)
      Run the given callable in a 'sandboxed' environment.
      source code
      call graph 
       
      introspect_docstring_lineno(api_doc)
      Try to determine the line number on which the given item's docstring begins.
      source code
       
      _is_zope_type(val) source code
       
      _is_zope_method(val) source code
      Variables [hide private]
        _valuedoc_cache = {135394656: <ValueDoc epydoc.docintrospecter...
      A cache containing the API documentation for values that we've already seen.
        _introspected_values = {135396096: True, 135400544: True, 1354...
      A record which values we've introspected, encoded as a dictionary from pyid to bool.
        UNDOCUMENTED_MODULE_VARS = ('__builtins__', '__doc__', '__all_...
      A list of module variables that should not be included in a module's API documentation.
        UNDOCUMENTED_CLASS_VARS = ('__doc__', '__module__', '__dict__'...
      A list of class variables that should not be included in a class's API documentation.
        _CLASS_TYPES = set([<type 'classobj'>, <type 'type'>])
      A list of types that should be treated as classes.
        __future_check_works = True
        _introspecter_registry = []
        _dev_null = sys.stdout
        _ZopeType = type(_ExtensionClass)
      Function Details [hide private]

      introspect_docs(value=None, name=None, filename=None, context=None, is_script=False, module_name=None)

      source code 
      call graph 

      Generate the API documentation for a specified object by introspecting Python values, and return it as a ValueDoc. The object to generate documentation for may be specified using the value parameter, the filename parameter, or the name parameter. (It is an error to specify more than one of these three parameters, or to not specify any of them.)

      Parameters:
      • value - The python object that should be documented.
      • filename - The name of the file that contains the python source code for a package, module, or script. If filename is specified, then introspect will return a ModuleDoc describing its contents.
      • name - The fully-qualified python dotted name of any value (including packages, modules, classes, and functions). DocParser will automatically figure out which module(s) it needs to import in order to find the documentation for the specified object.
      • context - The API documentation for the class of module that contains value (if available).
      • module_name - The name of the module where the value is defined. Useful to retrieve the docstring encoding if there is no way to detect the module by introspection (such as in properties)

      _get_valuedoc(value)

      source code 
      call graph 

      If a ValueDoc for the given value exists in the valuedoc cache, then return it; otherwise, create a new ValueDoc, add it to the cache, and return it. When possible, the new ValueDoc's pyval, repr, and canonical_name attributes will be set appropriately.

      isclass(object)

      source code 
      call graph 

      Return true if the given object is a class. In particular, return true if object is an instance of types.TypeType or of types.ClassType. This is used instead of inspect.isclass(), because the latter returns true for objects that are not classes (in particular, it returns true for any object that has a __bases__ attribute, including objects that define __getattr__ to always return a value).

      register_class_type(typ)

      source code 

      Add a type to the lists of types that should be treated as classes. By default, this list contains TypeType and ClassType.

      get_canonical_name(value, strict=False)

      source code 
      call graph 
      Returns: DottedName or UNKNOWN
      the canonical name for value, or UNKNOWN if no canonical name can be found. Currently, get_canonical_name can find canonical names for: modules; functions; non-nested classes; methods of non-nested classes; and some class methods of non-nested classes.

      verify_name(value, dotted_name)

      source code 
      call graph 

      Verify the name. E.g., if it's a nested class, then we won't be able to find it with the name we constructed.

      _find_function_module(func)

      source code 
      call graph 
      Parameters:
      • func (function) - The function whose module should be found.
      Returns: module
      The module that defines the given function.

      register_introspecter(applicability_test, introspecter, priority=10)

      source code 

      Register an introspecter function. Introspecter functions take two arguments, a python value and a ValueDoc object, and should add information about the given value to the the ValueDoc. Usually, the first line of an inspecter function will specialize it to a sublass of ValueDoc, using ValueDoc.specialize_to():

      >>> def typical_introspecter(value, value_doc):
      ...     value_doc.specialize_to(SomeSubclassOfValueDoc)
      ...     <add info to value_doc>
      Parameters:
      • priority - The priority of this introspecter, which determines the order in which introspecters are tried -- introspecters with lower numbers are tried first. The standard introspecters have priorities ranging from 20 to 30. The default priority (10) will place new introspecters before standard introspecters.

      get_value_from_name(name, globs=None)

      source code 

      Given a name, return the corresponding value.

      Parameters:
      • globs - A namespace to check for the value, if there is no module containing the named value. Defaults to __builtin__.

      _import(name, filename=None)

      source code 
      call graph 

      Run the given callable in a 'sandboxed' environment. Currently, this includes saving and restoring the contents of sys and __builtins__; and suppressing stdin, stdout, and stderr.

      introspect_docstring_lineno(api_doc)

      source code 

      Try to determine the line number on which the given item's docstring begins. Return the line number, or None if the line number can't be determined. The line number of the first line in the file is 1.


      Variables Details [hide private]

      _valuedoc_cache

      A cache containing the API documentation for values that we've already seen. This cache is implemented as a dictionary that maps a value's pyid to its ValueDoc.

      Note that if we encounter a value but decide not to introspect it (because it's imported from another module), then _valuedoc_cache will contain an entry for the value, but the value will not be listed in _introspected_values.

      Value:
      {135394656: <ValueDoc epydoc.docintrospecter.ClassType>,
       135394848: <ValueDoc epydoc.docintrospecter.InstanceType>,
       135395040: <ValueDoc epydoc.docintrospecter.MethodType>,
       135396096: <ClassDoc file>,
       135400544: <ClassDoc float>,
       135401088: <ClassDoc int>,
       135402368: <ClassDoc list>,
       135404832: <ClassDoc long>,
      ...
      

      _introspected_values

      A record which values we've introspected, encoded as a dictionary from pyid to bool.

      Value:
      {135396096: True,
       135400544: True,
       135401088: True,
       135402368: True,
       135404832: True,
       135405600: True,
       135408504: True,
       135408512: True,
      ...
      

      UNDOCUMENTED_MODULE_VARS

      A list of module variables that should not be included in a module's API documentation.

      Value:
      ('__builtins__',
       '__doc__',
       '__all__',
       '__file__',
       '__path__',
       '__name__',
       '__extra_epydoc_fields__',
       '__docformat__')
      

      UNDOCUMENTED_CLASS_VARS

      A list of class variables that should not be included in a class's API documentation.

      Value:
      ('__doc__',
       '__module__',
       '__dict__',
       '__weakref__',
       '__slots__',
       '__pyx_vtable__')
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext-pysrc.html0000644000175000017500000124202010750103050025747 0ustar pronovicpronovic epydoc.markup.restructuredtext
      Package epydoc :: Package markup :: Module restructuredtext
      [hide private]
      [frames] | no frames]

      Source Code for Module epydoc.markup.restructuredtext

        1  # 
        2  # rst.py: ReStructuredText docstring parsing 
        3  # Edward Loper 
        4  # 
        5  # Created [06/28/03 02:52 AM] 
        6  # $Id: restructuredtext.py 1661 2007-11-07 12:59:34Z dvarrazzo $ 
        7  # 
        8   
        9  """ 
       10  Epydoc parser for ReStructuredText strings.  ReStructuredText is the 
       11  standard markup language used by the Docutils project. 
       12  L{parse_docstring()} provides the primary interface to this module; it 
       13  returns a L{ParsedRstDocstring}, which supports all of the methods 
       14  defined by L{ParsedDocstring}. 
       15   
       16  L{ParsedRstDocstring} is basically just a L{ParsedDocstring} wrapper 
       17  for the C{docutils.nodes.document} class. 
       18   
       19  Creating C{ParsedRstDocstring}s 
       20  =============================== 
       21   
       22  C{ParsedRstDocstring}s are created by the C{parse_document} function, 
       23  using the C{docutils.core.publish_string()} method, with the following 
       24  helpers: 
       25   
       26    - An L{_EpydocReader} is used to capture all error messages as it 
       27      parses the docstring. 
       28    - A L{_DocumentPseudoWriter} is used to extract the document itself, 
       29      without actually writing any output.  The document is saved for 
       30      further processing.  The settings for the writer are copied from 
       31      C{docutils.writers.html4css1.Writer}, since those settings will 
       32      be used when we actually write the docstring to html. 
       33   
       34  Using C{ParsedRstDocstring}s 
       35  ============================ 
       36   
       37  C{ParsedRstDocstring}s support all of the methods defined by 
       38  C{ParsedDocstring}; but only the following four methods have 
       39  non-default behavior: 
       40   
       41    - L{to_html()<ParsedRstDocstring.to_html>} uses an 
       42      L{_EpydocHTMLTranslator} to translate the C{ParsedRstDocstring}'s 
       43      document into an HTML segment. 
       44    - L{split_fields()<ParsedRstDocstring.split_fields>} uses a 
       45      L{_SplitFieldsTranslator} to divide the C{ParsedRstDocstring}'s 
       46      document into its main body and its fields.  Special handling 
       47      is done to account for consolidated fields. 
       48    - L{summary()<ParsedRstDocstring.summary>} uses a 
       49      L{_SummaryExtractor} to extract the first sentence from 
       50      the C{ParsedRstDocstring}'s document. 
       51    - L{to_plaintext()<ParsedRstDocstring.to_plaintext>} uses 
       52      C{document.astext()} to convert the C{ParsedRstDocstring}'s 
       53      document to plaintext. 
       54   
       55  @todo: Add ParsedRstDocstring.to_latex() 
       56  @var CONSOLIDATED_FIELDS: A dictionary encoding the set of 
       57  'consolidated fields' that can be used.  Each consolidated field is 
       58  marked by a single tag, and contains a single bulleted list, where 
       59  each list item starts with an identifier, marked as interpreted text 
       60  (C{`...`}).  This module automatically splits these consolidated 
       61  fields into individual fields.  The keys of C{CONSOLIDATED_FIELDS} are 
       62  the names of possible consolidated fields; and the values are the 
       63  names of the field tags that should be used for individual entries in 
       64  the list. 
       65  """ 
       66  __docformat__ = 'epytext en' 
       67   
       68  # Imports 
       69  import re, os, os.path 
       70  from xml.dom.minidom import * 
       71   
       72  from docutils.core import publish_string 
       73  from docutils.writers import Writer 
       74  from docutils.writers.html4css1 import HTMLTranslator, Writer as HTMLWriter 
       75  from docutils.writers.latex2e import LaTeXTranslator, Writer as LaTeXWriter 
       76  from docutils.readers.standalone import Reader as StandaloneReader 
       77  from docutils.utils import new_document 
       78  from docutils.nodes import NodeVisitor, Text, SkipChildren 
       79  from docutils.nodes import SkipNode, TreeCopyVisitor 
       80  from docutils.frontend import OptionParser 
       81  from docutils.parsers.rst import directives, roles 
       82  import docutils.nodes 
       83  import docutils.transforms.frontmatter 
       84  import docutils.transforms 
       85  import docutils.utils 
       86   
       87  from epydoc.compat import * # Backwards compatibility 
       88  from epydoc.markup import * 
       89  from epydoc.apidoc import ModuleDoc, ClassDoc 
       90  from epydoc.docwriter.dotgraph import * 
       91  from epydoc.docwriter.xlink import ApiLinkReader 
       92  from epydoc.markup.doctest import doctest_to_html, doctest_to_latex, \ 
       93                                    HTMLDoctestColorizer 
       94   
       95  #: A dictionary whose keys are the "consolidated fields" that are 
       96  #: recognized by epydoc; and whose values are the corresponding epydoc 
       97  #: field names that should be used for the individual fields. 
       98  CONSOLIDATED_FIELDS = { 
       99      'parameters': 'param', 
      100      'arguments': 'arg', 
      101      'exceptions': 'except', 
      102      'variables': 'var', 
      103      'ivariables': 'ivar', 
      104      'cvariables': 'cvar', 
      105      'groups': 'group', 
      106      'types': 'type', 
      107      'keywords': 'keyword', 
      108      } 
      109   
      110  #: A list of consolidated fields whose bodies may be specified using a 
      111  #: definition list, rather than a bulleted list.  For these fields, the 
      112  #: 'classifier' for each term in the definition list is translated into 
      113  #: a @type field. 
      114  CONSOLIDATED_DEFLIST_FIELDS = ['param', 'arg', 'var', 'ivar', 'cvar', 'keyword'] 
      115   
      
      116 -def parse_docstring(docstring, errors, **options):
      117 """ 118 Parse the given docstring, which is formatted using 119 ReStructuredText; and return a L{ParsedDocstring} representation 120 of its contents. 121 @param docstring: The docstring to parse 122 @type docstring: C{string} 123 @param errors: A list where any errors generated during parsing 124 will be stored. 125 @type errors: C{list} of L{ParseError} 126 @param options: Extra options. Unknown options are ignored. 127 Currently, no extra options are defined. 128 @rtype: L{ParsedDocstring} 129 """ 130 writer = _DocumentPseudoWriter() 131 reader = _EpydocReader(errors) # Outputs errors to the list. 132 publish_string(docstring, writer=writer, reader=reader, 133 settings_overrides={'report_level':10000, 134 'halt_level':10000, 135 'warning_stream':None}) 136 return ParsedRstDocstring(writer.document)
      137
      138 -class OptimizedReporter(docutils.utils.Reporter):
      139 """A reporter that ignores all debug messages. This is used to 140 shave a couple seconds off of epydoc's run time, since docutils 141 isn't very fast about processing its own debug messages."""
      142 - def debug(self, *args, **kwargs): pass
      143
      144 -class ParsedRstDocstring(ParsedDocstring):
      145 """ 146 An encoded version of a ReStructuredText docstring. The contents 147 of the docstring are encoded in the L{_document} instance 148 variable. 149 150 @ivar _document: A ReStructuredText document, encoding the 151 docstring. 152 @type _document: C{docutils.nodes.document} 153 """
      154 - def __init__(self, document):
      155 """ 156 @type document: C{docutils.nodes.document} 157 """ 158 self._document = document 159 160 # The default document reporter and transformer are not 161 # pickle-able; so replace them with stubs that are. 162 document.reporter = OptimizedReporter( 163 document.reporter.source, 'SEVERE', 'SEVERE', '') 164 document.transformer = docutils.transforms.Transformer(document)
      165
      166 - def split_fields(self, errors=None):
      167 # Inherit docs 168 if errors is None: errors = [] 169 visitor = _SplitFieldsTranslator(self._document, errors) 170 self._document.walk(visitor) 171 if len(self._document.children) > 0: 172 return self, visitor.fields 173 else: 174 return None, visitor.fields
      175
      176 - def summary(self):
      177 # Inherit docs 178 visitor = _SummaryExtractor(self._document) 179 try: self._document.walk(visitor) 180 except docutils.nodes.NodeFound: pass 181 return visitor.summary, bool(visitor.other_docs)
      182 183 # def concatenate(self, other): 184 # result = self._document.copy() 185 # for child in (self._document.get_children() + 186 # other._document.get_children()): 187 # visitor = TreeCopyVisitor(self._document) 188 # child.walkabout(visitor) 189 # result.append(visitor.get_tree_copy()) 190 # return ParsedRstDocstring(result) 191
      192 - def to_html(self, docstring_linker, directory=None, 193 docindex=None, context=None, **options):
      194 # Inherit docs 195 visitor = _EpydocHTMLTranslator(self._document, docstring_linker, 196 directory, docindex, context) 197 self._document.walkabout(visitor) 198 return ''.join(visitor.body)
      199
      200 - def to_latex(self, docstring_linker, **options):
      201 # Inherit docs 202 visitor = _EpydocLaTeXTranslator(self._document, docstring_linker) 203 self._document.walkabout(visitor) 204 return ''.join(visitor.body)
      205
      206 - def to_plaintext(self, docstring_linker, **options):
      207 # This is should be replaced by something better: 208 return self._document.astext()
      209
      210 - def __repr__(self): return '<ParsedRstDocstring: ...>'
      211
      212 - def index_terms(self):
      213 visitor = _TermsExtractor(self._document) 214 self._document.walkabout(visitor) 215 return visitor.terms
      216
      217 -class _EpydocReader(ApiLinkReader):
      218 """ 219 A reader that captures all errors that are generated by parsing, 220 and appends them to a list. 221 """ 222 # Remove the DocInfo transform, to ensure that :author: fields are 223 # correctly handled. This needs to be handled differently 224 # depending on the version of docutils that's being used, because 225 # the default_transforms attribute was deprecated & replaced by 226 # get_transforms(). 227 version = [int(v) for v in docutils.__version__.split('.')] 228 version += [ 0 ] * (3 - len(version)) 229 if version < [0,4,0]: 230 default_transforms = list(ApiLinkReader.default_transforms) 231 try: default_transforms.remove(docutils.transforms.frontmatter.DocInfo) 232 except ValueError: pass 233 else:
      234 - def get_transforms(self):
      235 return [t for t in ApiLinkReader.get_transforms(self) 236 if t != docutils.transforms.frontmatter.DocInfo]
      237 del version 238
      239 - def __init__(self, errors):
      240 self._errors = errors 241 ApiLinkReader.__init__(self)
      242
      243 - def new_document(self):
      244 document = new_document(self.source.source_path, self.settings) 245 # Capture all warning messages. 246 document.reporter.attach_observer(self.report) 247 # These are used so we know how to encode warning messages: 248 self._encoding = document.reporter.encoding 249 self._error_handler = document.reporter.error_handler 250 # Return the new document. 251 return document
      252
      253 - def report(self, error):
      254 try: is_fatal = int(error['level']) > 2 255 except: is_fatal = 1 256 try: linenum = int(error['line']) 257 except: linenum = None 258 259 msg = ''.join([c.astext().encode(self._encoding, self._error_handler) 260 for c in error]) 261 262 self._errors.append(ParseError(msg, linenum, is_fatal))
      263
      264 -class _DocumentPseudoWriter(Writer):
      265 """ 266 A pseudo-writer for the docutils framework, that can be used to 267 access the document itself. The output of C{_DocumentPseudoWriter} 268 is just an empty string; but after it has been used, the most 269 recently processed document is available as the instance variable 270 C{document} 271 272 @type document: C{docutils.nodes.document} 273 @ivar document: The most recently processed document. 274 """
      275 - def __init__(self):
      276 self.document = None 277 Writer.__init__(self)
      278
      279 - def translate(self):
      280 self.output = ''
      281
      282 -class _SummaryExtractor(NodeVisitor):
      283 """ 284 A docutils node visitor that extracts the first sentence from 285 the first paragraph in a document. 286 """
      287 - def __init__(self, document):
      288 NodeVisitor.__init__(self, document) 289 self.summary = None 290 self.other_docs = None
      291
      292 - def visit_document(self, node):
      293 self.summary = None
      294 295 _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)')
      296 - def visit_paragraph(self, node):
      297 if self.summary is not None: 298 # found a paragraph after the first one 299 self.other_docs = True 300 raise docutils.nodes.NodeFound('Found summary') 301 302 summary_pieces = [] 303 304 # Extract the first sentence. 305 for child in node: 306 if isinstance(child, docutils.nodes.Text): 307 m = self._SUMMARY_RE.match(child.data) 308 if m: 309 summary_pieces.append(docutils.nodes.Text(m.group(1))) 310 other = child.data[m.end():] 311 if other and not other.isspace(): 312 self.other_docs = True 313 break 314 summary_pieces.append(child) 315 316 summary_doc = self.document.copy() # shallow copy 317 summary_para = node.copy() # shallow copy 318 summary_doc[:] = [summary_para] 319 summary_para[:] = summary_pieces 320 self.summary = ParsedRstDocstring(summary_doc)
      321
      322 - def visit_field(self, node):
      323 raise SkipNode
      324
      325 - def unknown_visit(self, node):
      326 'Ignore all unknown nodes'
      327
      328 -class _TermsExtractor(NodeVisitor):
      329 """ 330 A docutils node visitor that extracts the terms from documentation. 331 332 Terms are created using the C{:term:} interpreted text role. 333 """
      334 - def __init__(self, document):
      335 NodeVisitor.__init__(self, document) 336 337 self.terms = None 338 """ 339 The terms currently found. 340 @type: C{list} 341 """
      342
      343 - def visit_document(self, node):
      344 self.terms = [] 345 self._in_term = False
      346
      347 - def visit_emphasis(self, node):
      348 if 'term' in node.get('classes'): 349 self._in_term = True
      350
      351 - def depart_emphasis(self, node):
      352 if 'term' in node.get('classes'): 353 self._in_term = False
      354
      355 - def visit_Text(self, node):
      356 if self._in_term: 357 doc = self.document.copy() 358 doc[:] = [node.copy()] 359 self.terms.append(ParsedRstDocstring(doc))
      360
      361 - def unknown_visit(self, node):
      362 'Ignore all unknown nodes'
      363
      364 - def unknown_departure(self, node):
      365 'Ignore all unknown nodes'
      366
      367 -class _SplitFieldsTranslator(NodeVisitor):
      368 """ 369 A docutils translator that removes all fields from a document, and 370 collects them into the instance variable C{fields} 371 372 @ivar fields: The fields of the most recently walked document. 373 @type fields: C{list} of L{Field<markup.Field>} 374 """ 375 376 ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD = True 377 """If true, then consolidated fields are not required to mark 378 arguments with C{`backticks`}. (This is currently only 379 implemented for consolidated fields expressed as definition lists; 380 consolidated fields expressed as unordered lists still require 381 backticks for now.""" 382
      383 - def __init__(self, document, errors):
      384 NodeVisitor.__init__(self, document) 385 self._errors = errors 386 self.fields = [] 387 self._newfields = {}
      388
      389 - def visit_document(self, node):
      390 self.fields = []
      391
      392 - def visit_field(self, node):
      393 # Remove the field from the tree. 394 node.parent.remove(node) 395 396 # Extract the field name & optional argument 397 tag = node[0].astext().split(None, 1) 398 tagname = tag[0] 399 if len(tag)>1: arg = tag[1] 400 else: arg = None 401 402 # Handle special fields: 403 fbody = node[1] 404 if arg is None: 405 for (list_tag, entry_tag) in CONSOLIDATED_FIELDS.items(): 406 if tagname.lower() == list_tag: 407 try: 408 self.handle_consolidated_field(fbody, entry_tag) 409 return 410 except ValueError, e: 411 estr = 'Unable to split consolidated field ' 412 estr += '"%s" - %s' % (tagname, e) 413 self._errors.append(ParseError(estr, node.line, 414 is_fatal=0)) 415 416 # Use a @newfield to let it be displayed as-is. 417 if tagname.lower() not in self._newfields: 418 newfield = Field('newfield', tagname.lower(), 419 parse(tagname, 'plaintext')) 420 self.fields.append(newfield) 421 self._newfields[tagname.lower()] = 1 422 423 self._add_field(tagname, arg, fbody)
      424
      425 - def _add_field(self, tagname, arg, fbody):
      426 field_doc = self.document.copy() 427 for child in fbody: field_doc.append(child) 428 field_pdoc = ParsedRstDocstring(field_doc) 429 self.fields.append(Field(tagname, arg, field_pdoc))
      430
      431 - def visit_field_list(self, node):
      432 # Remove the field list from the tree. The visitor will still walk 433 # over the node's children. 434 node.parent.remove(node)
      435
      436 - def handle_consolidated_field(self, body, tagname):
      437 """ 438 Attempt to handle a consolidated section. 439 """ 440 if len(body) != 1: 441 raise ValueError('does not contain a single list.') 442 elif body[0].tagname == 'bullet_list': 443 self.handle_consolidated_bullet_list(body[0], tagname) 444 elif (body[0].tagname == 'definition_list' and 445 tagname in CONSOLIDATED_DEFLIST_FIELDS): 446 self.handle_consolidated_definition_list(body[0], tagname) 447 elif tagname in CONSOLIDATED_DEFLIST_FIELDS: 448 raise ValueError('does not contain a bulleted list or ' 449 'definition list.') 450 else: 451 raise ValueError('does not contain a bulleted list.')
      452
      453 - def handle_consolidated_bullet_list(self, items, tagname):
      454 # Check the contents of the list. In particular, each list 455 # item should have the form: 456 # - `arg`: description... 457 n = 0 458 _BAD_ITEM = ("list item %d is not well formed. Each item must " 459 "consist of a single marked identifier (e.g., `x`), " 460 "optionally followed by a colon or dash and a " 461 "description.") 462 for item in items: 463 n += 1 464 if item.tagname != 'list_item' or len(item) == 0: 465 raise ValueError('bad bulleted list (bad child %d).' % n) 466 if item[0].tagname != 'paragraph': 467 if item[0].tagname == 'definition_list': 468 raise ValueError(('list item %d contains a definition '+ 469 'list (it\'s probably indented '+ 470 'wrong).') % n) 471 else: 472 raise ValueError(_BAD_ITEM % n) 473 if len(item[0]) == 0: 474 raise ValueError(_BAD_ITEM % n) 475 if item[0][0].tagname != 'title_reference': 476 raise ValueError(_BAD_ITEM % n) 477 478 # Everything looks good; convert to multiple fields. 479 for item in items: 480 # Extract the arg 481 arg = item[0][0].astext() 482 483 # Extract the field body, and remove the arg 484 fbody = item[:] 485 fbody[0] = fbody[0].copy() 486 fbody[0][:] = item[0][1:] 487 488 # Remove the separating ":", if present 489 if (len(fbody[0]) > 0 and 490 isinstance(fbody[0][0], docutils.nodes.Text)): 491 child = fbody[0][0] 492 if child.data[:1] in ':-': 493 child.data = child.data[1:].lstrip() 494 elif child.data[:2] in (' -', ' :'): 495 child.data = child.data[2:].lstrip() 496 497 # Wrap the field body, and add a new field 498 self._add_field(tagname, arg, fbody)
      499
      500 - def handle_consolidated_definition_list(self, items, tagname):
      501 # Check the list contents. 502 n = 0 503 _BAD_ITEM = ("item %d is not well formed. Each item's term must " 504 "consist of a single marked identifier (e.g., `x`), " 505 "optionally followed by a space, colon, space, and " 506 "a type description.") 507 for item in items: 508 n += 1 509 if (item.tagname != 'definition_list_item' or len(item) < 2 or 510 item[0].tagname != 'term' or 511 item[-1].tagname != 'definition'): 512 raise ValueError('bad definition list (bad child %d).' % n) 513 if len(item) > 3: 514 raise ValueError(_BAD_ITEM % n) 515 if not ((item[0][0].tagname == 'title_reference') or 516 (self.ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD and 517 isinstance(item[0][0], docutils.nodes.Text))): 518 raise ValueError(_BAD_ITEM % n) 519 for child in item[0][1:]: 520 if child.astext() != '': 521 raise ValueError(_BAD_ITEM % n) 522 523 # Extract it. 524 for item in items: 525 # The basic field. 526 arg = item[0][0].astext() 527 fbody = item[-1] 528 self._add_field(tagname, arg, fbody) 529 # If there's a classifier, treat it as a type. 530 if len(item) == 3: 531 type_descr = item[1] 532 self._add_field('type', arg, type_descr)
      533
      534 - def unknown_visit(self, node):
      535 'Ignore all unknown nodes'
      536
      537 -def latex_head_prefix():
      538 document = new_document('<fake>') 539 translator = _EpydocLaTeXTranslator(document, None) 540 return translator.head_prefix
      541
      542 -class _EpydocLaTeXTranslator(LaTeXTranslator):
      543 settings = None
      544 - def __init__(self, document, docstring_linker):
      545 # Set the document's settings. 546 if self.settings is None: 547 settings = OptionParser([LaTeXWriter()]).get_default_values() 548 settings.output_encoding = 'utf-8' 549 self.__class__.settings = settings 550 document.settings = self.settings 551 552 LaTeXTranslator.__init__(self, document) 553 self._linker = docstring_linker 554 555 # Start at section level 3. (Unfortunately, we now have to 556 # set a private variable to make this work; perhaps the standard 557 # latex translator should grow an official way to spell this?) 558 self.section_level = 3 559 self._section_number = [0]*self.section_level
      560 561 # Handle interpreted text (crossreferences)
      562 - def visit_title_reference(self, node):
      563 target = self.encode(node.astext()) 564 xref = self._linker.translate_identifier_xref(target, target) 565 self.body.append(xref) 566 raise SkipNode()
      567
      568 - def visit_document(self, node): pass
      569 - def depart_document(self, node): pass
      570 571 # For now, just ignore dotgraphs. [XXX]
      572 - def visit_dotgraph(self, node):
      573 log.warning("Ignoring dotgraph in latex output (dotgraph " 574 "rendering for latex not implemented yet).") 575 raise SkipNode()
      576
      577 - def visit_doctest_block(self, node):
      578 self.body.append(doctest_to_latex(node[0].astext())) 579 raise SkipNode()
      580
      581 -class _EpydocHTMLTranslator(HTMLTranslator):
      582 settings = None
      583 - def __init__(self, document, docstring_linker, directory, 584 docindex, context):
      585 self._linker = docstring_linker 586 self._directory = directory 587 self._docindex = docindex 588 self._context = context 589 590 # Set the document's settings. 591 if self.settings is None: 592 settings = OptionParser([HTMLWriter()]).get_default_values() 593 self.__class__.settings = settings 594 document.settings = self.settings 595 596 # Call the parent constructor. 597 HTMLTranslator.__init__(self, document)
      598 599 # Handle interpreted text (crossreferences)
      600 - def visit_title_reference(self, node):
      601 target = self.encode(node.astext()) 602 xref = self._linker.translate_identifier_xref(target, target) 603 self.body.append(xref) 604 raise SkipNode()
      605
      606 - def should_be_compact_paragraph(self, node):
      607 if self.document.children == [node]: 608 return True 609 else: 610 return HTMLTranslator.should_be_compact_paragraph(self, node)
      611
      612 - def visit_document(self, node): pass
      613 - def depart_document(self, node): pass
      614
      615 - def starttag(self, node, tagname, suffix='\n', **attributes):
      616 """ 617 This modified version of starttag makes a few changes to HTML 618 tags, to prevent them from conflicting with epydoc. In particular: 619 - existing class attributes are prefixed with C{'rst-'} 620 - existing names are prefixed with C{'rst-'} 621 - hrefs starting with C{'#'} are prefixed with C{'rst-'} 622 - hrefs not starting with C{'#'} are given target='_top' 623 - all headings (C{<hM{n}>}) are given the css class C{'heading'} 624 """ 625 # Get the list of all attribute dictionaries we need to munge. 626 attr_dicts = [attributes] 627 if isinstance(node, docutils.nodes.Node): 628 attr_dicts.append(node.attributes) 629 if isinstance(node, dict): 630 attr_dicts.append(node) 631 # Munge each attribute dictionary. Unfortunately, we need to 632 # iterate through attributes one at a time because some 633 # versions of docutils don't case-normalize attributes. 634 for attr_dict in attr_dicts: 635 for (key, val) in attr_dict.items(): 636 # Prefix all CSS classes with "rst-"; and prefix all 637 # names with "rst-" to avoid conflicts. 638 if key.lower() in ('class', 'id', 'name'): 639 attr_dict[key] = 'rst-%s' % val 640 elif key.lower() in ('classes', 'ids', 'names'): 641 attr_dict[key] = ['rst-%s' % cls for cls in val] 642 elif key.lower() == 'href': 643 if attr_dict[key][:1]=='#': 644 attr_dict[key] = '#rst-%s' % attr_dict[key][1:] 645 else: 646 # If it's an external link, open it in a new 647 # page. 648 attr_dict['target'] = '_top' 649 650 # For headings, use class="heading" 651 if re.match(r'^h\d+$', tagname): 652 attributes['class'] = ' '.join([attributes.get('class',''), 653 'heading']).strip() 654 655 return HTMLTranslator.starttag(self, node, tagname, suffix, 656 **attributes)
      657
      658 - def visit_dotgraph(self, node):
      659 if self._directory is None: return # [xx] warning? 660 661 # Generate the graph. 662 graph = node.graph(self._docindex, self._context, self._linker) 663 if graph is None: return 664 665 # Write the graph. 666 image_url = '%s.gif' % graph.uid 667 image_file = os.path.join(self._directory, image_url) 668 self.body.append(graph.to_html(image_file, image_url)) 669 raise SkipNode()
      670
      671 - def visit_doctest_block(self, node):
      672 pysrc = node[0].astext() 673 if node.get('codeblock'): 674 self.body.append(HTMLDoctestColorizer().colorize_codeblock(pysrc)) 675 else: 676 self.body.append(doctest_to_html(pysrc)) 677 raise SkipNode()
      678
      679 - def visit_emphasis(self, node):
      680 # Generate a corrent index term anchor 681 if 'term' in node.get('classes') and node.children: 682 doc = self.document.copy() 683 doc[:] = [node.children[0].copy()] 684 self.body.append( 685 self._linker.translate_indexterm(ParsedRstDocstring(doc))) 686 raise SkipNode() 687 688 HTMLTranslator.visit_emphasis(self, node)
      689
      690 -def python_code_directive(name, arguments, options, content, lineno, 691 content_offset, block_text, state, state_machine):
      692 """ 693 A custom restructuredtext directive which can be used to display 694 syntax-highlighted Python code blocks. This directive takes no 695 arguments, and the body should contain only Python code. This 696 directive can be used instead of doctest blocks when it is 697 inconvenient to list prompts on each line, or when you would 698 prefer that the output not contain prompts (e.g., to make 699 copy/paste easier). 700 """ 701 required_arguments = 0 702 optional_arguments = 0 703 704 text = '\n'.join(content) 705 node = docutils.nodes.doctest_block(text, text, codeblock=True) 706 return [ node ]
      707 708 python_code_directive.arguments = (0, 0, 0) 709 python_code_directive.content = True 710 711 directives.register_directive('python', python_code_directive) 712
      713 -def term_role(name, rawtext, text, lineno, inliner, 714 options={}, content=[]):
      715 716 text = docutils.utils.unescape(text) 717 node = docutils.nodes.emphasis(rawtext, text, **options) 718 node.attributes['classes'].append('term') 719 720 return [node], []
      721 722 roles.register_local_role('term', term_role) 723 724 ###################################################################### 725 #{ Graph Generation Directives 726 ###################################################################### 727 # See http://docutils.sourceforge.net/docs/howto/rst-directives.html 728
      729 -class dotgraph(docutils.nodes.image):
      730 """ 731 A custom docutils node that should be rendered using Graphviz dot. 732 This node does not directly store the graph; instead, it stores a 733 pointer to a function that can be used to generate the graph. 734 This allows the graph to be built based on information that might 735 not be available yet at parse time. This graph generation 736 function has the following signature: 737 738 >>> def generate_graph(docindex, context, linker, *args): 739 ... 'generates and returns a new DotGraph' 740 741 Where C{docindex} is a docindex containing the documentation that 742 epydoc has built; C{context} is the C{APIDoc} whose docstring 743 contains this dotgraph node; C{linker} is a L{DocstringLinker} 744 that can be used to resolve crossreferences; and C{args} is any 745 extra arguments that are passed to the C{dotgraph} constructor. 746 """
      747 - def __init__(self, generate_graph_func, *generate_graph_args):
      748 docutils.nodes.image.__init__(self) 749 self.graph_func = generate_graph_func 750 self.args = generate_graph_args
      751 - def graph(self, docindex, context, linker):
      752 return self.graph_func(docindex, context, linker, *self.args)
      753
      754 -def _dir_option(argument):
      755 """A directive option spec for the orientation of a graph.""" 756 argument = argument.lower().strip() 757 if argument == 'right': return 'LR' 758 if argument == 'left': return 'RL' 759 if argument == 'down': return 'TB' 760 if argument == 'up': return 'BT' 761 raise ValueError('%r unknown; choose from left, right, up, down' % 762 argument)
      763
      764 -def digraph_directive(name, arguments, options, content, lineno, 765 content_offset, block_text, state, state_machine):
      766 """ 767 A custom restructuredtext directive which can be used to display 768 Graphviz dot graphs. This directive takes a single argument, 769 which is used as the graph's name. The contents of the directive 770 are used as the body of the graph. Any href attributes whose 771 value has the form <name> will be replaced by the URL of the object 772 with that name. Here's a simple example:: 773 774 .. digraph:: example_digraph 775 a -> b -> c 776 c -> a [dir=\"none\"] 777 """ 778 if arguments: title = arguments[0] 779 else: title = '' 780 return [ dotgraph(_construct_digraph, title, options.get('caption'), 781 '\n'.join(content)) ]
      782 digraph_directive.arguments = (0, 1, True) 783 digraph_directive.options = {'caption': directives.unchanged} 784 digraph_directive.content = True 785 directives.register_directive('digraph', digraph_directive) 786
      787 -def _construct_digraph(docindex, context, linker, title, caption, 788 body):
      789 """Graph generator for L{digraph_directive}""" 790 graph = DotGraph(title, body, caption=caption) 791 graph.link(linker) 792 return graph
      793
      794 -def classtree_directive(name, arguments, options, content, lineno, 795 content_offset, block_text, state, state_machine):
      796 """ 797 A custom restructuredtext directive which can be used to 798 graphically display a class hierarchy. If one or more arguments 799 are given, then those classes and all their descendants will be 800 displayed. If no arguments are given, and the directive is in a 801 class's docstring, then that class and all its descendants will be 802 displayed. It is an error to use this directive with no arguments 803 in a non-class docstring. 804 805 Options: 806 - C{:dir:} -- Specifies the orientation of the graph. One of 807 C{down}, C{right} (default), C{left}, C{up}. 808 """ 809 return [ dotgraph(_construct_classtree, arguments, options) ]
      810 classtree_directive.arguments = (0, 1, True) 811 classtree_directive.options = {'dir': _dir_option} 812 classtree_directive.content = False 813 directives.register_directive('classtree', classtree_directive) 814
      815 -def _construct_classtree(docindex, context, linker, arguments, options):
      816 """Graph generator for L{classtree_directive}""" 817 if len(arguments) == 1: 818 bases = [docindex.find(name, context) for name in 819 arguments[0].replace(',',' ').split()] 820 bases = [d for d in bases if isinstance(d, ClassDoc)] 821 elif isinstance(context, ClassDoc): 822 bases = [context] 823 else: 824 log.warning("Could not construct class tree: you must " 825 "specify one or more base classes.") 826 return None 827 828 return class_tree_graph(bases, linker, context, **options)
      829
      830 -def packagetree_directive(name, arguments, options, content, lineno, 831 content_offset, block_text, state, state_machine):
      832 """ 833 A custom restructuredtext directive which can be used to 834 graphically display a package hierarchy. If one or more arguments 835 are given, then those packages and all their submodules will be 836 displayed. If no arguments are given, and the directive is in a 837 package's docstring, then that package and all its submodules will 838 be displayed. It is an error to use this directive with no 839 arguments in a non-package docstring. 840 841 Options: 842 - C{:dir:} -- Specifies the orientation of the graph. One of 843 C{down}, C{right} (default), C{left}, C{up}. 844 """ 845 return [ dotgraph(_construct_packagetree, arguments, options) ]
      846 packagetree_directive.arguments = (0, 1, True) 847 packagetree_directive.options = { 848 'dir': _dir_option, 849 'style': lambda a:directives.choice(a.lower(), ('uml', 'tree'))} 850 packagetree_directive.content = False 851 directives.register_directive('packagetree', packagetree_directive) 852
      853 -def _construct_packagetree(docindex, context, linker, arguments, options):
      854 """Graph generator for L{packagetree_directive}""" 855 if len(arguments) == 1: 856 packages = [docindex.find(name, context) for name in 857 arguments[0].replace(',',' ').split()] 858 packages = [d for d in packages if isinstance(d, ModuleDoc)] 859 elif isinstance(context, ModuleDoc): 860 packages = [context] 861 else: 862 log.warning("Could not construct package tree: you must " 863 "specify one or more root packages.") 864 return None 865 866 return package_tree_graph(packages, linker, context, **options)
      867
      868 -def importgraph_directive(name, arguments, options, content, lineno, 869 content_offset, block_text, state, state_machine):
      870 return [ dotgraph(_construct_importgraph, arguments, options) ]
      871 importgraph_directive.arguments = (0, 1, True) 872 importgraph_directive.options = {'dir': _dir_option} 873 importgraph_directive.content = False 874 directives.register_directive('importgraph', importgraph_directive) 875
      876 -def _construct_importgraph(docindex, context, linker, arguments, options):
      877 """Graph generator for L{importgraph_directive}""" 878 if len(arguments) == 1: 879 modules = [ docindex.find(name, context) 880 for name in arguments[0].replace(',',' ').split() ] 881 modules = [d for d in modules if isinstance(d, ModuleDoc)] 882 else: 883 modules = [d for d in docindex.root if isinstance(d, ModuleDoc)] 884 885 return import_graph(modules, docindex, linker, context, **options)
      886
      887 -def callgraph_directive(name, arguments, options, content, lineno, 888 content_offset, block_text, state, state_machine):
      889 return [ dotgraph(_construct_callgraph, arguments, options) ]
      890 callgraph_directive.arguments = (0, 1, True) 891 callgraph_directive.options = {'dir': _dir_option, 892 'add_callers': directives.flag, 893 'add_callees': directives.flag} 894 callgraph_directive.content = False 895 directives.register_directive('callgraph', callgraph_directive) 896
      897 -def _construct_callgraph(docindex, context, linker, arguments, options):
      898 """Graph generator for L{callgraph_directive}""" 899 if len(arguments) == 1: 900 docs = [docindex.find(name, context) for name in 901 arguments[0].replace(',',' ').split()] 902 docs = [doc for doc in docs if doc is not None] 903 else: 904 docs = [context] 905 return call_graph(docs, docindex, linker, context, **options)
      906

      epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr-pysrc.html0000644000175000017500000065162710750103050024512 0ustar pronovicpronovic epydoc.markup.pyval_repr
      Package epydoc :: Package markup :: Module pyval_repr
      [hide private]
      [frames] | no frames]

      Source Code for Module epydoc.markup.pyval_repr

        1  # epydoc -- Marked-up Representations for Python Values 
        2  # 
        3  # Copyright (C) 2005 Edward Loper 
        4  # Author: Edward Loper <edloper@loper.org> 
        5  # URL: <http://epydoc.sf.net> 
        6  # 
        7  # $Id: apidoc.py 1448 2007-02-11 00:05:34Z dvarrazzo $ 
        8   
        9  """ 
       10  Syntax highlighter for Python values.  Currently provides special 
       11  colorization support for: 
       12   
       13    - lists, tuples, sets, frozensets, dicts 
       14    - numbers 
       15    - strings 
       16    - compiled regexps 
       17   
       18  The highlighter also takes care of line-wrapping, and automatically 
       19  stops generating repr output as soon as it has exceeded the specified 
       20  number of lines (which should make it faster than pprint for large 
       21  values).  It does I{not} bother to do automatic cycle detection, 
       22  because maxlines is typically around 5, so it's really not worth it. 
       23   
       24  The syntax-highlighted output is encoded using a 
       25  L{ParsedEpytextDocstring}, which can then be used to generate output in 
       26  a variety of formats. 
       27  """ 
       28  __docformat__ = 'epytext en' 
       29   
       30  # Implementation note: we use exact tests for classes (list, etc) 
       31  # rather than using isinstance, because subclasses might override 
       32  # __repr__. 
       33   
       34  import types, re 
       35  import epydoc.apidoc 
       36  from epydoc.util import decode_with_backslashreplace 
       37  from epydoc.util import plaintext_to_html, plaintext_to_latex 
       38  from epydoc.compat import * 
       39  import sre_parse, sre_constants 
       40   
       41  from epydoc.markup.epytext import Element, ParsedEpytextDocstring 
       42   
      
      43 -def is_re_pattern(pyval):
      44 return type(pyval).__name__ == 'SRE_Pattern'
      45
      46 -class _ColorizerState:
      47 """ 48 An object uesd to keep track of the current state of the pyval 49 colorizer. The L{mark()}/L{restore()} methods can be used to set 50 a backup point, and restore back to that backup point. This is 51 used by several colorization methods that first try colorizing 52 their object on a single line (setting linebreakok=False); and 53 then fall back on a multi-line output if that fails. The L{score} 54 variable is used to keep track of a 'score', reflecting how good 55 we think this repr is. E.g., unhelpful values like '<Foo instance 56 at 0x12345>' get low scores. If the score is too low, we'll use 57 the parse-derived repr instead. 58 """
      59 - def __init__(self):
      60 self.result = [] 61 self.charpos = 0 62 self.lineno = 1 63 self.linebreakok = True 64 65 #: How good this represention is? 66 self.score = 0
      67
      68 - def mark(self):
      69 return (len(self.result), self.charpos, 70 self.lineno, self.linebreakok, self.score)
      71
      72 - def restore(self, mark):
      73 n, self.charpos, self.lineno, self.linebreakok, self.score = mark 74 del self.result[n:]
      75
      76 -class _Maxlines(Exception):
      77 """A control-flow exception that is raised when PyvalColorizer 78 exeeds the maximum number of allowed lines."""
      79
      80 -class _Linebreak(Exception):
      81 """A control-flow exception that is raised when PyvalColorizer 82 generates a string containing a newline, but the state object's 83 linebreakok variable is False."""
      84
      85 -class ColorizedPyvalRepr(ParsedEpytextDocstring):
      86 """ 87 @ivar score: A score, evaluating how good this repr is. 88 @ivar is_complete: True if this colorized repr completely describes 89 the object. 90 """
      91 - def __init__(self, tree, score, is_complete):
      92 ParsedEpytextDocstring.__init__(self, tree) 93 self.score = score 94 self.is_complete = is_complete
      95
      96 -def colorize_pyval(pyval, parse_repr=None, min_score=None, 97 linelen=75, maxlines=5, linebreakok=True, sort=True):
      98 return PyvalColorizer(linelen, maxlines, linebreakok, sort).colorize( 99 pyval, parse_repr, min_score)
      100
      101 -class PyvalColorizer:
      102 """ 103 Syntax highlighter for Python values. 104 """ 105
      106 - def __init__(self, linelen=75, maxlines=5, linebreakok=True, sort=True):
      107 self.linelen = linelen 108 self.maxlines = maxlines 109 self.linebreakok = linebreakok 110 self.sort = sort
      111 112 #//////////////////////////////////////////////////////////// 113 # Colorization Tags & other constants 114 #//////////////////////////////////////////////////////////// 115 116 GROUP_TAG = 'variable-group' # e.g., "[" and "]" 117 COMMA_TAG = 'variable-op' # The "," that separates elements 118 COLON_TAG = 'variable-op' # The ":" in dictionaries 119 CONST_TAG = None # None, True, False 120 NUMBER_TAG = None # ints, floats, etc 121 QUOTE_TAG = 'variable-quote' # Quotes around strings. 122 STRING_TAG = 'variable-string' # Body of string literals 123 124 RE_CHAR_TAG = None 125 RE_GROUP_TAG = 're-group' 126 RE_REF_TAG = 're-ref' 127 RE_OP_TAG = 're-op' 128 RE_FLAGS_TAG = 're-flags' 129 130 ELLIPSIS = Element('code', u'...', style='variable-ellipsis') 131 LINEWRAP = Element('symbol', u'crarr') 132 UNKNOWN_REPR = Element('code', u'??', style='variable-unknown') 133 134 GENERIC_OBJECT_RE = re.compile(r'^<.* at 0x[0-9a-f]+>$', re.IGNORECASE) 135 136 ESCAPE_UNICODE = False # should we escape non-ascii unicode chars? 137 138 #//////////////////////////////////////////////////////////// 139 # Entry Point 140 #//////////////////////////////////////////////////////////// 141
      142 - def colorize(self, pyval, parse_repr=None, min_score=None):
      143 """ 144 @return: A L{ColorizedPyvalRepr} describing the given pyval. 145 """ 146 UNKNOWN = epydoc.apidoc.UNKNOWN 147 # Create an object to keep track of the colorization. 148 state = _ColorizerState() 149 state.linebreakok = self.linebreakok 150 # Colorize the value. If we reach maxlines, then add on an 151 # ellipsis marker and call it a day. 152 try: 153 if pyval is not UNKNOWN: 154 self._colorize(pyval, state) 155 elif parse_repr not in (None, UNKNOWN): 156 self._output(parse_repr, None, state) 157 else: 158 state.result.append(PyvalColorizer.UNKNOWN_REPR) 159 is_complete = True 160 except (_Maxlines, _Linebreak): 161 if self.linebreakok: 162 state.result.append('\n') 163 state.result.append(self.ELLIPSIS) 164 else: 165 if state.result[-1] is self.LINEWRAP: 166 state.result.pop() 167 self._trim_result(state.result, 3) 168 state.result.append(self.ELLIPSIS) 169 is_complete = False 170 # If we didn't score high enough, then try again. 171 if (pyval is not UNKNOWN and parse_repr not in (None, UNKNOWN) 172 and min_score is not None and state.score < min_score): 173 return self.colorize(UNKNOWN, parse_repr) 174 # Put it all together. 175 tree = Element('epytext', *state.result) 176 return ColorizedPyvalRepr(tree, state.score, is_complete)
      177
      178 - def _colorize(self, pyval, state):
      179 pyval_type = type(pyval) 180 state.score += 1 181 182 if pyval is None or pyval is True or pyval is False: 183 self._output(unicode(pyval), self.CONST_TAG, state) 184 elif pyval_type in (int, float, long, types.ComplexType): 185 self._output(unicode(pyval), self.NUMBER_TAG, state) 186 elif pyval_type is str: 187 self._colorize_str(pyval, state, '', 'string-escape') 188 elif pyval_type is unicode: 189 if self.ESCAPE_UNICODE: 190 self._colorize_str(pyval, state, 'u', 'unicode-escape') 191 else: 192 self._colorize_str(pyval, state, 'u', None) 193 elif pyval_type is list: 194 self._multiline(self._colorize_iter, pyval, state, '[', ']') 195 elif pyval_type is tuple: 196 self._multiline(self._colorize_iter, pyval, state, '(', ')') 197 elif pyval_type is set: 198 self._multiline(self._colorize_iter, self._sort(pyval), 199 state, 'set([', '])') 200 elif pyval_type is frozenset: 201 self._multiline(self._colorize_iter, self._sort(pyval), 202 state, 'frozenset([', '])') 203 elif pyval_type is dict: 204 self._multiline(self._colorize_dict, self._sort(pyval.items()), 205 state, '{', '}') 206 elif is_re_pattern(pyval): 207 self._colorize_re(pyval, state) 208 else: 209 try: 210 pyval_repr = repr(pyval) 211 if not isinstance(pyval_repr, (str, unicode)): 212 pyval_repr = unicode(pyval_repr) 213 pyval_repr_ok = True 214 except KeyboardInterrupt: 215 raise 216 except: 217 pyval_repr_ok = False 218 state.score -= 100 219 220 if pyval_repr_ok: 221 if self.GENERIC_OBJECT_RE.match(pyval_repr): 222 state.score -= 5 223 self._output(pyval_repr, None, state) 224 else: 225 state.result.append(self.UNKNOWN_REPR)
      226
      227 - def _sort(self, items):
      228 if not self.sort: return items 229 try: return sorted(items) 230 except KeyboardInterrupt: raise 231 except: return items
      232
      233 - def _trim_result(self, result, num_chars):
      234 while num_chars > 0: 235 if not result: return 236 if isinstance(result[-1], Element): 237 assert len(result[-1].children) == 1 238 trim = min(num_chars, len(result[-1].children[0])) 239 result[-1].children[0] = result[-1].children[0][:-trim] 240 if not result[-1].children[0]: result.pop() 241 num_chars -= trim 242 else: 243 trim = min(num_chars, len(result[-1])) 244 result[-1] = result[-1][:-trim] 245 if not result[-1]: result.pop() 246 num_chars -= trim
      247 248 #//////////////////////////////////////////////////////////// 249 # Object Colorization Functions 250 #//////////////////////////////////////////////////////////// 251
      252 - def _multiline(self, func, pyval, state, *args):
      253 """ 254 Helper for container-type colorizers. First, try calling 255 C{func(pyval, state, *args)} with linebreakok set to false; 256 and if that fails, then try again with it set to true. 257 """ 258 linebreakok = state.linebreakok 259 mark = state.mark() 260 261 try: 262 state.linebreakok = False 263 func(pyval, state, *args) 264 state.linebreakok = linebreakok 265 266 except _Linebreak: 267 if not linebreakok: 268 raise 269 state.restore(mark) 270 func(pyval, state, *args)
      271
      272 - def _colorize_iter(self, pyval, state, prefix, suffix):
      273 self._output(prefix, self.GROUP_TAG, state) 274 indent = state.charpos 275 for i, elt in enumerate(pyval): 276 if i>=1: 277 if state.linebreakok: 278 self._output(',', self.COMMA_TAG, state) 279 self._output('\n'+' '*indent, None, state) 280 else: 281 self._output(', ', self.COMMA_TAG, state) 282 self._colorize(elt, state) 283 self._output(suffix, self.GROUP_TAG, state)
      284
      285 - def _colorize_dict(self, items, state, prefix, suffix):
      286 self._output(prefix, self.GROUP_TAG, state) 287 indent = state.charpos 288 for i, (key, val) in enumerate(items): 289 if i>=1: 290 if state.linebreakok: 291 self._output(',', self.COMMA_TAG, state) 292 self._output('\n'+' '*indent, None, state) 293 else: 294 self._output(', ', self.COMMA_TAG, state) 295 self._colorize(key, state) 296 self._output(': ', self.COLON_TAG, state) 297 self._colorize(val, state) 298 self._output(suffix, self.GROUP_TAG, state)
      299
      300 - def _colorize_str(self, pyval, state, prefix, encoding):
      301 # Decide which quote to use. 302 if '\n' in pyval and state.linebreakok: quote = "'''" 303 else: quote = "'" 304 # Divide the string into lines. 305 if state.linebreakok: 306 lines = pyval.split('\n') 307 else: 308 lines = [pyval] 309 # Open quote. 310 self._output(prefix+quote, self.QUOTE_TAG, state) 311 # Body 312 for i, line in enumerate(lines): 313 if i>0: self._output('\n', None, state) 314 if encoding: line = line.encode(encoding) 315 self._output(line, self.STRING_TAG, state) 316 # Close quote. 317 self._output(quote, self.QUOTE_TAG, state)
      318
      319 - def _colorize_re(self, pyval, state):
      320 # Extract the flag & pattern from the regexp. 321 pat, flags = pyval.pattern, pyval.flags 322 # If the pattern is a string, decode it to unicode. 323 if isinstance(pat, str): 324 pat = decode_with_backslashreplace(pat) 325 # Parse the regexp pattern. 326 tree = sre_parse.parse(pat, flags) 327 groups = dict([(num,name) for (name,num) in 328 tree.pattern.groupdict.items()]) 329 # Colorize it! 330 self._output("re.compile(r'", None, state) 331 self._colorize_re_flags(tree.pattern.flags, state) 332 self._colorize_re_tree(tree, state, True, groups) 333 self._output("')", None, state)
      334
      335 - def _colorize_re_flags(self, flags, state):
      336 if flags: 337 flags = [c for (c,n) in sorted(sre_parse.FLAGS.items()) 338 if (n&flags)] 339 flags = '(?%s)' % ''.join(flags) 340 self._output(flags, self.RE_FLAGS_TAG, state)
      341
      342 - def _colorize_re_tree(self, tree, state, noparen, groups):
      343 assert noparen in (True, False) 344 if len(tree) > 1 and not noparen: 345 self._output('(', self.RE_GROUP_TAG, state) 346 for elt in tree: 347 op = elt[0] 348 args = elt[1] 349 350 if op == sre_constants.LITERAL: 351 c = unichr(args) 352 # Add any appropriate escaping. 353 if c in '.^$\\*+?{}[]|()\'': c = '\\'+c 354 elif c == '\t': c = '\\t' 355 elif c == '\r': c = '\\r' 356 elif c == '\n': c = '\\n' 357 elif c == '\f': c = '\\f' 358 elif c == '\v': c = '\\v' 359 elif ord(c) > 0xffff: c = r'\U%08x' % ord(c) 360 elif ord(c) > 0xff: c = r'\u%04x' % ord(c) 361 elif ord(c)<32 or ord(c)>=127: c = r'\x%02x' % ord(c) 362 self._output(c, self.RE_CHAR_TAG, state) 363 364 elif op == sre_constants.ANY: 365 self._output('.', self.RE_CHAR_TAG, state) 366 367 elif op == sre_constants.BRANCH: 368 if args[0] is not None: 369 raise ValueError('Branch expected None arg but got %s' 370 % args[0]) 371 for i, item in enumerate(args[1]): 372 if i > 0: 373 self._output('|', self.RE_OP_TAG, state) 374 self._colorize_re_tree(item, state, True, groups) 375 376 elif op == sre_constants.IN: 377 if (len(args) == 1 and args[0][0] == sre_constants.CATEGORY): 378 self._colorize_re_tree(args, state, False, groups) 379 else: 380 self._output('[', self.RE_GROUP_TAG, state) 381 self._colorize_re_tree(args, state, True, groups) 382 self._output(']', self.RE_GROUP_TAG, state) 383 384 elif op == sre_constants.CATEGORY: 385 if args == sre_constants.CATEGORY_DIGIT: val = r'\d' 386 elif args == sre_constants.CATEGORY_NOT_DIGIT: val = r'\D' 387 elif args == sre_constants.CATEGORY_SPACE: val = r'\s' 388 elif args == sre_constants.CATEGORY_NOT_SPACE: val = r'\S' 389 elif args == sre_constants.CATEGORY_WORD: val = r'\w' 390 elif args == sre_constants.CATEGORY_NOT_WORD: val = r'\W' 391 else: raise ValueError('Unknown category %s' % args) 392 self._output(val, self.RE_CHAR_TAG, state) 393 394 elif op == sre_constants.AT: 395 if args == sre_constants.AT_BEGINNING_STRING: val = r'\A' 396 elif args == sre_constants.AT_BEGINNING: val = r'^' 397 elif args == sre_constants.AT_END: val = r'$' 398 elif args == sre_constants.AT_BOUNDARY: val = r'\b' 399 elif args == sre_constants.AT_NON_BOUNDARY: val = r'\B' 400 elif args == sre_constants.AT_END_STRING: val = r'\Z' 401 else: raise ValueError('Unknown position %s' % args) 402 self._output(val, self.RE_CHAR_TAG, state) 403 404 elif op in (sre_constants.MAX_REPEAT, sre_constants.MIN_REPEAT): 405 minrpt = args[0] 406 maxrpt = args[1] 407 if maxrpt == sre_constants.MAXREPEAT: 408 if minrpt == 0: val = '*' 409 elif minrpt == 1: val = '+' 410 else: val = '{%d,}' % (minrpt) 411 elif minrpt == 0: 412 if maxrpt == 1: val = '?' 413 else: val = '{,%d}' % (maxrpt) 414 elif minrpt == maxrpt: 415 val = '{%d}' % (maxrpt) 416 else: 417 val = '{%d,%d}' % (minrpt, maxrpt) 418 if op == sre_constants.MIN_REPEAT: 419 val += '?' 420 421 self._colorize_re_tree(args[2], state, False, groups) 422 self._output(val, self.RE_OP_TAG, state) 423 424 elif op == sre_constants.SUBPATTERN: 425 if args[0] is None: 426 self._output('(?:', self.RE_GROUP_TAG, state) 427 elif args[0] in groups: 428 self._output('(?P<', self.RE_GROUP_TAG, state) 429 self._output(groups[args[0]], self.RE_REF_TAG, state) 430 self._output('>', self.RE_GROUP_TAG, state) 431 elif isinstance(args[0], (int, long)): 432 # This is cheating: 433 self._output('(', self.RE_GROUP_TAG, state) 434 else: 435 self._output('(?P<', self.RE_GROUP_TAG, state) 436 self._output(args[0], self.RE_REF_TAG, state) 437 self._output('>', self.RE_GROUP_TAG, state) 438 self._colorize_re_tree(args[1], state, True, groups) 439 self._output(')', self.RE_GROUP_TAG, state) 440 441 elif op == sre_constants.GROUPREF: 442 self._output('\\%d' % args, self.RE_REF_TAG, state) 443 444 elif op == sre_constants.RANGE: 445 self._colorize_re_tree( ((sre_constants.LITERAL, args[0]),), 446 state, False, groups ) 447 self._output('-', self.RE_OP_TAG, state) 448 self._colorize_re_tree( ((sre_constants.LITERAL, args[1]),), 449 state, False, groups ) 450 451 elif op == sre_constants.NEGATE: 452 self._output('^', self.RE_OP_TAG, state) 453 454 elif op == sre_constants.ASSERT: 455 if args[0] > 0: 456 self._output('(?=', self.RE_GROUP_TAG, state) 457 else: 458 self._output('(?<=', self.RE_GROUP_TAG, state) 459 self._colorize_re_tree(args[1], state, True, groups) 460 self._output(')', self.RE_GROUP_TAG, state) 461 462 elif op == sre_constants.ASSERT_NOT: 463 if args[0] > 0: 464 self._output('(?!', self.RE_GROUP_TAG, state) 465 else: 466 self._output('(?<!', self.RE_GROUP_TAG, state) 467 self._colorize_re_tree(args[1], state, True, groups) 468 self._output(')', self.RE_GROUP_TAG, state) 469 470 elif op == sre_constants.NOT_LITERAL: 471 self._output('[^', self.RE_GROUP_TAG, state) 472 self._colorize_re_tree( ((sre_constants.LITERAL, args),), 473 state, False, groups ) 474 self._output(']', self.RE_GROUP_TAG, state) 475 else: 476 log.error("Error colorizing regexp: unknown elt %r" % elt) 477 if len(tree) > 1 and not noparen: 478 self._output(')', self.RE_GROUP_TAG, state)
      479 480 #//////////////////////////////////////////////////////////// 481 # Output function 482 #//////////////////////////////////////////////////////////// 483
      484 - def _output(self, s, tag, state):
      485 """ 486 Add the string `s` to the result list, tagging its contents 487 with tag `tag`. Any lines that go beyond `self.linelen` will 488 be line-wrapped. If the total number of lines exceeds 489 `self.maxlines`, then raise a `_Maxlines` exception. 490 """ 491 # Make sure the string is unicode. 492 if isinstance(s, str): 493 s = decode_with_backslashreplace(s) 494 495 # Split the string into segments. The first segment is the 496 # content to add to the current line, and the remaining 497 # segments are new lines. 498 segments = s.split('\n') 499 500 for i, segment in enumerate(segments): 501 # If this isn't the first segment, then add a newline to 502 # split it from the previous segment. 503 if i > 0: 504 if (state.lineno+1) > self.maxlines: 505 raise _Maxlines() 506 if not state.linebreakok: 507 raise _Linebreak() 508 state.result.append(u'\n') 509 state.lineno += 1 510 state.charpos = 0 511 512 # If the segment fits on the current line, then just call 513 # markup to tag it, and store the result. 514 if state.charpos + len(segment) <= self.linelen: 515 state.charpos += len(segment) 516 if tag: 517 segment = Element('code', segment, style=tag) 518 state.result.append(segment) 519 520 # If the segment doesn't fit on the current line, then 521 # line-wrap it, and insert the remainder of the line into 522 # the segments list that we're iterating over. (We'll go 523 # the the beginning of the next line at the start of the 524 # next iteration through the loop.) 525 else: 526 split = self.linelen-state.charpos 527 segments.insert(i+1, segment[split:]) 528 segment = segment[:split] 529 if tag: 530 segment = Element('code', segment, style=tag) 531 state.result += [segment, self.LINEWRAP]
      532

      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter-pysrc.html0000644000175000017500000001354210750103050023017 0ustar pronovicpronovic epydoc.docwriter
      Package epydoc :: Package docwriter
      [hide private]
      [frames] | no frames]

      Source Code for Package epydoc.docwriter

       1  # epydoc -- Output generation 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: __init__.py 956 2006-03-10 01:30:51Z edloper $ 
       8   
       9  """ 
      10  Output generation. 
      11  """ 
      12  __docformat__ = 'epytext en' 
      13   
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph-module.html0000644000175000017500000020430010750103050024745 0ustar pronovicpronovic epydoc.docwriter.dotgraph
      Package epydoc :: Package docwriter :: Module dotgraph
      [hide private]
      [frames] | no frames]

      Module dotgraph

      source code

      Render Graphviz directed graphs as images. Below are some examples.

      Import Graph
      Import Graph

      Class Hierarchy for apidoc.APIDoc
      Class Hierarchy for apidoc.APIDoc

      Package Tree for epydoc
      Package Tree for epydoc


      Classes [hide private]
          Dot Graphs
        DotGraph
      A dot directed graph.
        DotGraphNode
        DotGraphEdge
          Specialized Nodes for UML Graphs
        DotGraphUmlClassNode
      A specialized dot graph node used to display ClassDocs using UML notation.
        DotGraphUmlModuleNode
      A specialized dot grah node used to display ModuleDocs using UML notation.
      Functions [hide private]
          Graph Generation Functions
       
      package_tree_graph(packages, linker, context=None, **options)
      Return a DotGraph that graphically displays the package hierarchies for the given packages.
      source code
      call graph 
       
      uml_package_tree_graph(packages, linker, context=None, **options)
      Return a DotGraph that graphically displays the package hierarchies for the given packages as a nested set of UML symbols.
      source code
      call graph 
       
      class_tree_graph(bases, linker, context=None, **options)
      Return a DotGraph that graphically displays the class hierarchy for the given classes.
      source code
      call graph 
       
      uml_class_tree_graph(class_doc, linker, context=None, **options)
      Return a DotGraph that graphically displays the class hierarchy for the given class, using UML notation.
      source code
      call graph 
       
      import_graph(modules, docindex, linker, context=None, **options) source code
      call graph 
       
      call_graph(api_docs, docindex, linker, context=None, **options) source code
          Dot Version
       
      get_dot_version() source code
      call graph 
          Helper Functions
       
      add_valdoc_nodes(graph, val_docs, linker, context) source code
      call graph 
       
      specialize_valdoc_node(node, val_doc, context, url)
      Update the style attributes of node to reflext its type and context.
      source code
      call graph 
       
      name_list(api_docs, context=None) source code
      call graph 
      Variables [hide private]
        MODULE_BG = '#d8e8ff'
        CLASS_BG = '#d8ffe8'
        SELECTED_BG = '#ffd0d0'
        BASECLASS_BG = '#e0b0a0'
        SUBCLASS_BG = '#e0b0a0'
        ROUTINE_BG = '#e8d0b0'
        INH_LINK_COLOR = '#800000'
          Dot Graphs
        DOT_COMMAND = 'dot'
      The command that should be used to spawn dot
          Dot Version
        _dot_version = None
        _DOT_VERSION_RE = re.compile(r'dot version ([\d\.]+)')
          Helper Functions
        NOOP_URL = 'javascript:void(0);'
        MODULE_NODE_HTML = '<TABLE BORDER="0" CELLBORDER="0" CELLSPACI...
      Function Details [hide private]

      class_tree_graph(bases, linker, context=None, **options)

      source code 
      call graph 

      Return a DotGraph that graphically displays the class hierarchy for the given classes. Options:

      • exclude
      • dir: LR|RL|BT requests a left-to-right, right-to-left, or bottom-to- top, drawing. (corresponds to the dot option 'rankdir'

      uml_class_tree_graph(class_doc, linker, context=None, **options)

      source code 
      call graph 

      Return a DotGraph that graphically displays the class hierarchy for the given class, using UML notation. Options:

      • max_attributes
      • max_operations
      • show_private_vars
      • show_magic_vars
      • link_attributes

      call_graph(api_docs, docindex, linker, context=None, **options)

      source code 
      Parameters:
      • options -
        • dir: rankdir for the graph. (default=LR)
        • add_callers: also include callers for any of the routines in api_docs. (default=False)
        • add_callees: also include callees for any of the routines in api_docs. (default=False)

      To Do: Add an exclude option?

      add_valdoc_nodes(graph, val_docs, linker, context)

      source code 
      call graph 

      To Do: Use different node styles for different subclasses of APIDoc


      Variables Details [hide private]

      MODULE_NODE_HTML

      Value:
      '''<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0"
               CELLPADDING="0" PORT="table" ALIGN="LEFT">
        <TR><TD ALIGN="LEFT" VALIGN="BOTTOM" HEIGHT="8" WIDTH="16" FIXEDSIZE\
      ="true"
                BGCOLOR="%s" BORDER="1" PORT="tab"></TD></TR>
        <TR><TD ALIGN="LEFT" VALIGN="TOP" BGCOLOR="%s" BORDER="1"
                PORT="body" HREF="%s" TOOLTIP="%s">%s</TD></TR>
        </TABLE>'''
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.Element-class.html0000644000175000017500000003312410750103050025350 0ustar pronovicpronovic epydoc.markup.epytext.Element
      Package epydoc :: Package markup :: Module epytext :: Class Element
      [hide private]
      [frames] | no frames]

      Class Element

      source code

      A very simple DOM-like representation for parsed epytext documents. Each epytext document is encoded as a tree whose nodes are Element objects, and whose leaves are strings. Each node is marked by a tag and zero or more attributes. Each attribute is a mapping from a string key to a string value.

      Instance Methods [hide private]
       
      __init__(self, tag, *children, **attribs) source code
      call graph 
       
      __str__(self)
      Return a string representation of this element, using XML notation.
      source code
       
      __repr__(self) source code
      Instance Variables [hide private]
      string tag
      A string tag indicating the type of this element.
      list of (string or Element) children
      A list of the children of this element.
      dict from string to string attribs
      A dictionary mapping attribute names to attribute values for this element.
      Method Details [hide private]

      __str__(self)
      (Informal representation operator)

      source code 

      Return a string representation of this element, using XML notation.

      Bug: Doesn't escape '<' or '&' or '>'.


      epydoc-3.0.1+dfsg/doc/api/epydoc.docstringparser-module.html0000644000175000017500000035442710750103050024365 0ustar pronovicpronovic epydoc.docstringparser
      Package epydoc :: Module docstringparser
      [hide private]
      [frames] | no frames]

      Module docstringparser

      source code

      Parse docstrings and handle any fields it defines, such as @type and @author. Fields are used to describe specific information about an object. There are two classes of fields: simple fields and special fields.

      Simple fields are fields that get stored directly in an APIDoc's metadata dictionary, without any special processing. The set of simple fields is defined by the list STANDARD_FIELDS, whose elements are DocstringFields.

      Special fields are fields that perform some sort of processing on the APIDoc, or add information to attributes other than the metadata dictionary. Special fields are are handled by field handler functions, which are registered using register_field_handler.

      Classes [hide private]
        DocstringField
      A simple docstring field, which can be used to describe specific information about an object, such as its author or its version.
      Functions [hide private]
          Docstring Parsing
       
      parse_docstring(api_doc, docindex, suppress_warnings=[])
      Process the given APIDoc's docstring.
      source code
      call graph 
       
      add_metadata_from_var(api_doc, field) source code
      call graph 
       
      initialize_api_doc(api_doc)
      A helper function for parse_docstring() that initializes the attributes that parse_docstring() will write to.
      source code
      call graph 
      list of markup.Field
      split_init_fields(fields, warnings)
      Remove the fields related to the constructor from a class docstring fields list.
      source code
      call graph 
       
      report_errors(api_doc, docindex, parse_errors, field_warnings)
      A helper function for parse_docstring() that reports any markup warnings and field warnings that we encountered while processing api_doc's docstring.
      source code
      call graph 
          Field Processing
       
      process_field(api_doc, docindex, tag, arg, descr)
      Process a single field, and use it to update api_doc.
      source code
      call graph 
       
      user_docfields(api_doc, docindex)
      Return a list of user defined fields that can be used for the given object.
      source code
      call graph 
       
      register_field_handler(handler, *field_tags)
      Register the given field handler function for processing any of the given field tags.
      source code
          Field Handler Functions
       
      process_summary_field(api_doc, docindex, tag, arg, descr)
      Store descr in api_doc.summary
      source code
       
      process_include_field(api_doc, docindex, tag, arg, descr)
      Copy the docstring contents from the object named in descr
      source code
       
      process_undocumented_field(api_doc, docindex, tag, arg, descr)
      Remove any documentation for the variables named in descr
      source code
       
      process_group_field(api_doc, docindex, tag, arg, descr)
      Define a group named arg containing the variables whose names are listed in descr.
      source code
      call graph 
       
      process_deffield_field(api_doc, docindex, tag, arg, descr)
      Define a new custom field.
      source code
      call graph 
       
      process_raise_field(api_doc, docindex, tag, arg, descr)
      Record the fact that api_doc can raise the exception named tag in api_doc.exception_descrs.
      source code
      call graph 
       
      process_sort_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_type_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_var_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_cvar_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_ivar_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_return_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_rtype_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_arg_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
       
      process_kwarg_field(api_doc, docindex, tag, arg, descr) source code
      call graph 
          Helper Functions
       
      check_type_fields(api_doc, field_warnings)
      Check to make sure that all type fields correspond to some documented parameter; if not, append a warning to field_warnings.
      source code
      call graph 
       
      set_var_descr(api_doc, ident, descr) source code
      call graph 
       
      set_var_type(api_doc, ident, descr) source code
      call graph 
       
      _check(api_doc, tag, arg, context=None, expect_arg=None) source code
      call graph 
       
      get_docformat(api_doc, docindex)
      Return the name of the markup language that should be used to parse the API documentation for the given object.
      source code
      call graph 
       
      unindent_docstring(docstring) source code
      call graph 
      list of string
      _descr_to_identifiers(descr)
      Given a ParsedDocstring that contains a list of identifiers, return a list of those identifiers.
      source code
      call graph 
       
      _descr_to_docstring_field(arg, descr) source code
      call graph 
          Function Signature Extraction
      None
      parse_function_signature(func_doc, doc_source, docformat, parse_errors)
      Construct the signature for a builtin function or method from its docstring.
      source code
      call graph 
      Variables [hide private]
        STANDARD_FIELDS = [<Field: deprecated>, <Field: version>, <Fie...
      A list of the standard simple fields accepted by epydoc.
          Docstring Parsing
        DEFAULT_DOCFORMAT = 'plaintext'
      The name of the default markup languge used to process docstrings.
        RETURN_PDS = markup.parse('Returns:', markup= 'epytext')
      A ParsedDocstring containing the text 'Returns'.
          Field Processing Error Messages
        UNEXPECTED_ARG = '%r did not expect an argument'
        EXPECTED_ARG = '%r expected an argument'
        EXPECTED_SINGLE_ARG = '%r expected a single argument'
        BAD_CONTEXT = 'Invalid context for %r'
        REDEFINED = 'Redefinition of %s'
        UNKNOWN_TAG = 'Unknown field tag %r'
        BAD_PARAM = '@%s for unknown parameter %s'
          Field Processing
        _field_dispatch_table = {}
          Field Handler Functions
        PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param', 'kw...
        VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable')
        EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception')
          Helper Functions
        _IDENTIFIER_LIST_REGEXP = re.compile(r'^[\w\.\*]+([\s,:;]\s*[\...
          Function Signature Extraction
        _SIGNATURE_RE = re.compile(r'^\s*((?P<self>\w+)\.)?(?P<func>\w...
      A regular expression that is used to extract signatures from docstrings.
      Function Details [hide private]

      parse_docstring(api_doc, docindex, suppress_warnings=[])

      source code 
      call graph 

      Process the given APIDoc's docstring. In particular, populate the APIDoc's descr and summary attributes, and add any information provided by fields in the docstring.

      Parameters:
      • docindex - A DocIndex, used to find the containing module (to look up the docformat); and to find any user docfields defined by containing objects.
      • suppress_warnings - A set of objects for which docstring warnings should be suppressed.

      split_init_fields(fields, warnings)

      source code 
      call graph 

      Remove the fields related to the constructor from a class docstring fields list.

      Parameters:
      • fields (list of markup.Field) - The fields to process. The list will be modified in place
      • warnings (list) - A list to emit processing warnings
      Returns: list of markup.Field
      The fields items to be applied to the __init__ method

      process_field(api_doc, docindex, tag, arg, descr)

      source code 
      call graph 

      Process a single field, and use it to update api_doc. If tag is the name of a special field, then call its handler function. If tag is the name of a simple field, then use process_simple_field to process it. Otherwise, check if it's a user-defined field, defined in this docstring or the docstring of a containing object; and if so, process it with process_simple_field.

      Parameters:
      • tag - The field's tag, such as 'author'
      • arg - The field's optional argument
      • descr - The description following the field tag and argument.
      Raises:
      • ValueError - If a problem was encountered while processing the field. The ValueError's string argument is an explanation of the problem, which should be displayed as a warning message.

      user_docfields(api_doc, docindex)

      source code 
      call graph 

      Return a list of user defined fields that can be used for the given object. This list is taken from the given api_doc, and any of its containing NamepaceDocs.

      Note: We assume here that a parent's docstring will always be parsed before its childrens'. This is indeed the case when we are called via docbuilder.build_doc_index(). If a child's docstring is parsed before its parents, then its parent won't yet have had its extra_docstring_fields attribute initialized.

      register_field_handler(handler, *field_tags)

      source code 

      Register the given field handler function for processing any of the given field tags. Field handler functions should have the following signature:

      >>> def field_handler(api_doc, docindex, tag, arg, descr):
      ...     '''update api_doc in response to the field.'''

      Where api_doc is the documentation object to update; docindex is a DocIndex that can be used to look up the documentation for related objects; tag is the field tag that was used; arg is the optional argument; and descr is the description following the field tag and argument.

      _descr_to_identifiers(descr)

      source code 
      call graph 

      Given a ParsedDocstring that contains a list of identifiers, return a list of those identifiers. This is used by fields such as @group and @sort, which expect lists of identifiers as their values. To extract the identifiers, the docstring is first converted to plaintext, and then split. The plaintext content of the docstring must be a a list of identifiers, separated by spaces, commas, colons, or semicolons.

      Parameters:
      Returns: list of string
      A list of the identifier names contained in descr.
      Raises:
      • ValueError - If descr does not contain a valid list of identifiers.

      parse_function_signature(func_doc, doc_source, docformat, parse_errors)

      source code 
      call graph 

      Construct the signature for a builtin function or method from its docstring. If the docstring uses the standard convention of including a signature in the first line of the docstring (and formats that signature according to standard conventions), then it will be used to extract a signature. Otherwise, the signature will be set to a single varargs variable named "...".

      Parameters:
      • func_doc (RoutineDoc) - The target object where to store parsed signature. Also container of the docstring to parse if doc_source is None
      • doc_source (APIDoc) - Contains the docstring to parse. If None, parse func_doc docstring instead
      Returns: None

      Variables Details [hide private]

      STANDARD_FIELDS

      A list of the standard simple fields accepted by epydoc. This list can be augmented at run-time by a docstring with the special @deffield field. The order in which fields are listed here determines the order in which they will be displayed in the output.

      Value:
      [<Field: deprecated>,
       <Field: version>,
       <Field: date>,
       <Field: status>,
       <Field: author>,
       <Field: contact>,
       <Field: organization>,
       <Field: copyright>,
      ...
      

      RETURN_PDS

      A ParsedDocstring containing the text 'Returns'. This is used to construct summary descriptions for routines that have empty descr, but non-empty return_descr.

      Value:
      markup.parse('Returns:', markup= 'epytext')
      

      PARAMETER_TAGS

      Value:
      ('arg',
       'argument',
       'parameter',
       'param',
       'kwarg',
       'keyword',
       'kwparam')
      

      _IDENTIFIER_LIST_REGEXP

      Value:
      re.compile(r'^[\w\.\*]+([\s,:;]\s*[\w\.\*]+)*$')
      

      _SIGNATURE_RE

      A regular expression that is used to extract signatures from docstrings.

      Value:
      re.compile(r'^\s*((?P<self>\w+)\.)?(?P<func>\w+)\((?P<params>(\s*\[?\s\
      *\*{,2}[\w-\.]+(\s*=.+?)?(\s*\[?\s*,\s*\]?\s*\*{,2}[\w-\.]+(\s*=.+?)?)\
      *\]*)?)\s*\)(\s*(->)\s*(?P<return>\S.*?))?\s*(\n|\s+(--|<=+>)\s+|$|\.\\
      s+|\.\n)')
      

      epydoc-3.0.1+dfsg/doc/api/toc-epydoc.cli-module.html0000644000175000017500000001032110750103050022464 0ustar pronovicpronovic cli

      Module cli


      Classes

      ConsoleLogger
      HTMLLogger
      TerminalController
      UnifiedProgressConsoleLogger

      Functions

      check_docs
      cli
      main
      parse_arguments
      parse_configfiles
      pickle_persistent_id
      pickle_persistent_load
      write_html
      write_latex
      write_pickle
      write_text

      Variables

      ACTIONS
      DEFAULT_DOCFORMAT
      DOCFORMATS
      GRAPH_TYPES
      HELP_TOPICS
      INHERITANCE_STYLES
      OPTION_DEFAULTS
      PROFILER
      descr
      key
      sheet
      topic

      [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.ConcatenatedDocstring-class.html0000644000175000017500000003513710750103050026531 0ustar pronovicpronovic epydoc.markup.ConcatenatedDocstring
      Package epydoc :: Package markup :: Class ConcatenatedDocstring
      [hide private]
      [frames] | no frames]

      Class ConcatenatedDocstring

      source code

      Instance Methods [hide private]
       
      __init__(self, *parsed_docstrings) source code
      call graph 
       
      split_fields(self, errors=None) source code
       
      summary(self) source code
       
      to_html(self, docstring_linker, **options) source code
      call graph 
       
      to_latex(self, docstring_linker, **options) source code
       
      to_plaintext(self, docstring_linker, **options) source code
      call graph 
       
      index_terms(self) source code
      call graph 
      epydoc-3.0.1+dfsg/doc/api/epydoc.docbuilder-pysrc.html0000644000175000017500000165337010750103050023143 0ustar pronovicpronovic epydoc.docbuilder
      Package epydoc :: Module docbuilder
      [hide private]
      [frames] | no frames]

      Source Code for Module epydoc.docbuilder

         1  # epydoc -- Documentation Builder 
         2  # 
         3  # Copyright (C) 2005 Edward Loper 
         4  # Author: Edward Loper <edloper@loper.org> 
         5  # URL: <http://epydoc.sf.net> 
         6  # 
         7  # $Id: docbuilder.py 1683 2008-01-29 22:17:39Z edloper $ 
         8   
         9  """ 
        10  Construct data structures that encode the API documentation for Python 
        11  objects.  These data structures are created using a series of steps: 
        12   
        13    1. B{Building docs}: Extract basic information about the objects, 
        14       and objects that are related to them.  This can be done by 
        15       introspecting the objects' values (with L{epydoc.docintrospecter}; or 
        16       by parsing their source code (with L{epydoc.docparser}. 
        17   
        18    2. B{Merging}: Combine the information obtained from introspection & 
        19       parsing each object into a single structure. 
        20   
        21    3. B{Linking}: Replace any 'pointers' that were created for imported 
        22       variables by their target (if it's available). 
        23     
        24    4. B{Naming}: Chose a unique 'canonical name' for each 
        25       object. 
        26     
        27    5. B{Docstring Parsing}: Parse the docstring of each object, and 
        28       extract any pertinant information. 
        29     
        30    6. B{Inheritance}: Add information about variables that classes 
        31       inherit from their base classes. 
        32   
        33  The documentation information for each individual object is 
        34  represented using an L{APIDoc}; and the documentation for a collection 
        35  of objects is represented using a L{DocIndex}. 
        36   
        37  The main interface to C{epydoc.docbuilder} consists of two functions: 
        38   
        39    - L{build_doc()} -- Builds documentation for a single item, and 
        40      returns it as an L{APIDoc} object. 
        41    - L{build_doc_index()} -- Builds documentation for a collection of 
        42      items, and returns it as a L{DocIndex} object. 
        43   
        44  The remaining functions are used by these two main functions to 
        45  perform individual steps in the creation of the documentation. 
        46   
        47  @group Documentation Construction: build_doc, build_doc_index, 
        48      _get_docs_from_*, _report_valdoc_progress 
        49  @group Merging: *MERGE*, *merge* 
        50  @group Linking: link_imports 
        51  @group Naming: _name_scores, _unreachable_names, assign_canonical_names, 
        52      _var_shadows_self, _fix_self_shadowing_var, _unreachable_name_for 
        53  @group Inheritance: inherit_docs, _inherit_info 
        54  """ 
        55  __docformat__ = 'epytext en' 
        56   
        57  ###################################################################### 
        58  ## Contents 
        59  ###################################################################### 
        60  ## 1. build_doc() & build_doc_index() -- the main interface. 
        61  ## 2. merge_docs() -- helper, used to merge parse & introspect info 
        62  ## 3. link_imports() -- helper, used to connect imported vars w/ values 
        63  ## 4. assign_canonical_names() -- helper, used to set canonical names 
        64  ## 5. inherit_docs() -- helper, used to inherit docs from base classes 
        65   
        66  ###################################################################### 
        67  ## Imports 
        68  ###################################################################### 
        69   
        70  import sys, os, os.path, __builtin__, imp, re, inspect 
        71  from epydoc.apidoc import * 
        72  from epydoc.docintrospecter import introspect_docs 
        73  from epydoc.docparser import parse_docs, ParseError 
        74  from epydoc.docstringparser import parse_docstring 
        75  from epydoc import log 
        76  from epydoc.util import * 
        77  from epydoc.compat import * # Backwards compatibility 
        78   
        79  ###################################################################### 
        80  ## 1. build_doc() 
        81  ###################################################################### 
        82   
      
      83 -class BuildOptions:
      84 """ 85 Holds the parameters for a documentation building process. 86 """
      87 - def __init__(self, introspect=True, parse=True, 88 exclude_introspect=None, exclude_parse=None, 89 add_submodules=True):
      90 self.introspect = introspect 91 self.parse = parse 92 self.exclude_introspect = exclude_introspect 93 self.exclude_parse = exclude_parse 94 self.add_submodules = add_submodules 95 96 # Test for pattern syntax and compile them into pattern objects. 97 try: 98 self._introspect_regexp = (exclude_introspect 99 and re.compile(exclude_introspect) or None) 100 self._parse_regexp = (exclude_parse 101 and re.compile(exclude_parse) or None) 102 except Exception, exc: 103 log.error('Error in regular expression pattern: %s' % exc) 104 raise
      105
      106 - def must_introspect(self, name):
      107 """ 108 Return C{True} if a module is to be introsepcted with the current 109 settings. 110 111 @param name: The name of the module to test 112 @type name: L{DottedName} or C{str} 113 """ 114 return self.introspect \ 115 and not self._matches_filter(name, self._introspect_regexp)
      116
      117 - def must_parse(self, name):
      118 """ 119 Return C{True} if a module is to be parsed with the current settings. 120 121 @param name: The name of the module to test 122 @type name: L{DottedName} or C{str} 123 """ 124 return self.parse \ 125 and not self._matches_filter(name, self._parse_regexp)
      126
      127 - def _matches_filter(self, name, regexp):
      128 """ 129 Test if a module name matches a pattern. 130 131 @param name: The name of the module to test 132 @type name: L{DottedName} or C{str} 133 @param regexp: The pattern object to match C{name} against. 134 If C{None}, return C{False} 135 @type regexp: C{pattern} 136 @return: C{True} if C{name} in dotted format matches C{regexp}, 137 else C{False} 138 @rtype: C{bool} 139 """ 140 if regexp is None: return False 141 142 if isinstance(name, DottedName): 143 name = str(name) 144 145 return bool(regexp.search(name))
      146 147
      148 -def build_doc(item, introspect=True, parse=True, add_submodules=True, 149 exclude_introspect=None, exclude_parse=None):
      150 """ 151 Build API documentation for a given item, and return it as 152 an L{APIDoc} object. 153 154 @rtype: L{APIDoc} 155 @param item: The item to document, specified using any of the 156 following: 157 - A string, naming a python package directory 158 (e.g., C{'epydoc/markup'}) 159 - A string, naming a python file 160 (e.g., C{'epydoc/docparser.py'}) 161 - A string, naming a python object 162 (e.g., C{'epydoc.docparser.DocParser'}) 163 - Any (non-string) python object 164 (e.g., C{list.append}) 165 @param introspect: If true, then use introspection to examine the 166 specified items. Otherwise, just use parsing. 167 @param parse: If true, then use parsing to examine the specified 168 items. Otherwise, just use introspection. 169 """ 170 docindex = build_doc_index([item], introspect, parse, add_submodules, 171 exclude_introspect=exclude_introspect, 172 exclude_parse=exclude_parse) 173 return docindex.root[0]
      174
      175 -def build_doc_index(items, introspect=True, parse=True, add_submodules=True, 176 exclude_introspect=None, exclude_parse=None):
      177 """ 178 Build API documentation for the given list of items, and 179 return it in the form of a L{DocIndex}. 180 181 @rtype: L{DocIndex} 182 @param items: The items to document, specified using any of the 183 following: 184 - A string, naming a python package directory 185 (e.g., C{'epydoc/markup'}) 186 - A string, naming a python file 187 (e.g., C{'epydoc/docparser.py'}) 188 - A string, naming a python object 189 (e.g., C{'epydoc.docparser.DocParser'}) 190 - Any (non-string) python object 191 (e.g., C{list.append}) 192 @param introspect: If true, then use introspection to examine the 193 specified items. Otherwise, just use parsing. 194 @param parse: If true, then use parsing to examine the specified 195 items. Otherwise, just use introspection. 196 """ 197 try: 198 options = BuildOptions(parse=parse, introspect=introspect, 199 exclude_introspect=exclude_introspect, exclude_parse=exclude_parse, 200 add_submodules=add_submodules) 201 except Exception, e: 202 # log.error already reported by constructor. 203 return None 204 205 # Get the basic docs for each item. 206 doc_pairs = _get_docs_from_items(items, options) 207 208 # Merge the introspection & parse docs. 209 if options.parse and options.introspect: 210 log.start_progress('Merging parsed & introspected information') 211 docs = [] 212 for i, (introspect_doc, parse_doc) in enumerate(doc_pairs): 213 if introspect_doc is not None and parse_doc is not None: 214 if introspect_doc.canonical_name not in (None, UNKNOWN): 215 name = introspect_doc.canonical_name 216 else: 217 name = parse_doc.canonical_name 218 log.progress(float(i)/len(doc_pairs), name) 219 docs.append(merge_docs(introspect_doc, parse_doc)) 220 elif introspect_doc is not None: 221 docs.append(introspect_doc) 222 elif parse_doc is not None: 223 docs.append(parse_doc) 224 log.end_progress() 225 elif options.introspect: 226 docs = [doc_pair[0] for doc_pair in doc_pairs if doc_pair[0]] 227 else: 228 docs = [doc_pair[1] for doc_pair in doc_pairs if doc_pair[1]] 229 230 if len(docs) == 0: 231 log.error('Nothing left to document!') 232 return None 233 234 # Collect the docs into a single index. 235 docindex = DocIndex(docs) 236 237 # Replace any proxy valuedocs that we got from importing with 238 # their targets. 239 if options.parse: 240 log.start_progress('Linking imported variables') 241 valdocs = sorted(docindex.reachable_valdocs( 242 imports=False, submodules=False, packages=False, subclasses=False)) 243 for i, val_doc in enumerate(valdocs): 244 _report_valdoc_progress(i, val_doc, valdocs) 245 link_imports(val_doc, docindex) 246 log.end_progress() 247 248 # Assign canonical names. 249 log.start_progress('Indexing documentation') 250 for i, val_doc in enumerate(docindex.root): 251 log.progress(float(i)/len(docindex.root), val_doc.canonical_name) 252 assign_canonical_names(val_doc, val_doc.canonical_name, docindex) 253 log.end_progress() 254 255 # Set overrides pointers 256 log.start_progress('Checking for overridden methods') 257 valdocs = sorted(docindex.reachable_valdocs( 258 imports=False, submodules=False, packages=False, subclasses=False)) 259 for i, val_doc in enumerate(valdocs): 260 if isinstance(val_doc, ClassDoc): 261 percent = float(i)/len(valdocs) 262 log.progress(percent, val_doc.canonical_name) 263 find_overrides(val_doc) 264 log.end_progress() 265 266 # Parse the docstrings for each object. 267 log.start_progress('Parsing docstrings') 268 suppress_warnings = set(valdocs).difference( 269 docindex.reachable_valdocs( 270 imports=False, submodules=False, packages=False, subclasses=False, 271 bases=False, overrides=True)) 272 for i, val_doc in enumerate(valdocs): 273 _report_valdoc_progress(i, val_doc, valdocs) 274 # the value's docstring 275 parse_docstring(val_doc, docindex, suppress_warnings) 276 # the value's variables' docstrings 277 if (isinstance(val_doc, NamespaceDoc) and 278 val_doc.variables not in (None, UNKNOWN)): 279 for var_doc in val_doc.variables.values(): 280 # Now we have a chance to propagate the defining module 281 # to objects for which introspection is not possible, 282 # such as properties. 283 if (isinstance(var_doc.value, ValueDoc) 284 and var_doc.value.defining_module is UNKNOWN): 285 var_doc.value.defining_module = val_doc.defining_module 286 parse_docstring(var_doc, docindex, suppress_warnings) 287 log.end_progress() 288 289 # Take care of inheritance. 290 log.start_progress('Inheriting documentation') 291 for i, val_doc in enumerate(valdocs): 292 if isinstance(val_doc, ClassDoc): 293 percent = float(i)/len(valdocs) 294 log.progress(percent, val_doc.canonical_name) 295 inherit_docs(val_doc) 296 log.end_progress() 297 298 # Initialize the groups & sortedvars attributes. 299 log.start_progress('Sorting & Grouping') 300 for i, val_doc in enumerate(valdocs): 301 if isinstance(val_doc, NamespaceDoc): 302 percent = float(i)/len(valdocs) 303 log.progress(percent, val_doc.canonical_name) 304 val_doc.init_sorted_variables() 305 val_doc.init_variable_groups() 306 if isinstance(val_doc, ModuleDoc): 307 val_doc.init_submodule_groups() 308 val_doc.report_unused_groups() 309 log.end_progress() 310 311 return docindex
      312
      313 -def _report_valdoc_progress(i, val_doc, val_docs):
      314 if (isinstance(val_doc, (ModuleDoc, ClassDoc)) and 315 val_doc.canonical_name is not UNKNOWN and 316 not val_doc.canonical_name[0].startswith('??')): 317 log.progress(float(i)/len(val_docs), val_doc.canonical_name)
      318 319 #///////////////////////////////////////////////////////////////// 320 # Documentation Generation 321 #///////////////////////////////////////////////////////////////// 322
      323 -def _get_docs_from_items(items, options):
      324 325 # Start the progress bar. 326 log.start_progress('Building documentation') 327 progress_estimator = _ProgressEstimator(items) 328 329 # Check for duplicate item names. 330 item_set = set() 331 for item in items[:]: 332 if item in item_set: 333 log.warning("Name %r given multiple times" % item) 334 items.remove(item) 335 item_set.add(item) 336 337 # Keep track of what top-level canonical names we've assigned, to 338 # make sure there are no naming conflicts. This dict maps 339 # canonical names to the item names they came from (so we can print 340 # useful error messages). 341 canonical_names = {} 342 343 # Collect (introspectdoc, parsedoc) pairs for each item. 344 doc_pairs = [] 345 for item in items: 346 if isinstance(item, basestring): 347 if is_module_file(item): 348 doc_pairs.append(_get_docs_from_module_file( 349 item, options, progress_estimator)) 350 elif is_package_dir(item): 351 pkgfile = os.path.abspath(os.path.join(item, '__init__')) 352 doc_pairs.append(_get_docs_from_module_file( 353 pkgfile, options, progress_estimator)) 354 elif os.path.isfile(item): 355 doc_pairs.append(_get_docs_from_pyscript( 356 item, options, progress_estimator)) 357 elif hasattr(__builtin__, item): 358 val = getattr(__builtin__, item) 359 doc_pairs.append(_get_docs_from_pyobject( 360 val, options, progress_estimator)) 361 elif is_pyname(item): 362 doc_pairs.append(_get_docs_from_pyname( 363 item, options, progress_estimator)) 364 elif os.path.isdir(item): 365 log.error("Directory %r is not a package" % item) 366 continue 367 elif os.path.isfile(item): 368 log.error("File %s is not a Python module" % item) 369 continue 370 else: 371 log.error("Could not find a file or object named %s" % 372 item) 373 continue 374 else: 375 doc_pairs.append(_get_docs_from_pyobject( 376 item, options, progress_estimator)) 377 378 # Make sure there are no naming conflicts. 379 name = (getattr(doc_pairs[-1][0], 'canonical_name', None) or 380 getattr(doc_pairs[-1][1], 'canonical_name', None)) 381 if name in canonical_names: 382 log.error( 383 'Two of the specified items, %r and %r, have the same ' 384 'canonical name ("%s"). This may mean that you specified ' 385 'two different files that both use the same module name. ' 386 'Ignoring the second item (%r)' % 387 (canonical_names[name], item, name, canonical_names[name])) 388 doc_pairs.pop() 389 else: 390 canonical_names[name] = item 391 392 # This will only have an effect if doc_pairs[-1] contains a 393 # package's docs. The 'not is_module_file(item)' prevents 394 # us from adding subdirectories if they explicitly specify 395 # a package's __init__.py file. 396 if options.add_submodules and not is_module_file(item): 397 doc_pairs += _get_docs_from_submodules( 398 item, doc_pairs[-1], options, progress_estimator) 399 400 log.end_progress() 401 return doc_pairs
      402
      403 -def _get_docs_from_pyobject(obj, options, progress_estimator):
      404 progress_estimator.complete += 1 405 log.progress(progress_estimator.progress(), repr(obj)) 406 407 if not options.introspect: 408 log.error("Cannot get docs for Python objects without " 409 "introspecting them.") 410 411 introspect_doc = parse_doc = None 412 introspect_error = parse_error = None 413 try: 414 introspect_doc = introspect_docs(value=obj) 415 except ImportError, e: 416 log.error(e) 417 return (None, None) 418 if options.parse: 419 if introspect_doc.canonical_name is not None: 420 prev_introspect = options.introspect 421 options.introspect = False 422 try: 423 _, parse_docs = _get_docs_from_pyname( 424 str(introspect_doc.canonical_name), options, 425 progress_estimator, suppress_warnings=True) 426 finally: 427 options.introspect = prev_introspect 428 429 # We need a name: 430 if introspect_doc.canonical_name in (None, UNKNOWN): 431 if hasattr(obj, '__name__'): 432 introspect_doc.canonical_name = DottedName( 433 DottedName.UNREACHABLE, obj.__name__) 434 else: 435 introspect_doc.canonical_name = DottedName( 436 DottedName.UNREACHABLE) 437 return (introspect_doc, parse_doc)
      438
      439 -def _get_docs_from_pyname(name, options, progress_estimator, 440 suppress_warnings=False):
      441 progress_estimator.complete += 1 442 if options.must_introspect(name) or options.must_parse(name): 443 log.progress(progress_estimator.progress(), name) 444 445 introspect_doc = parse_doc = None 446 introspect_error = parse_error = None 447 if options.must_introspect(name): 448 try: 449 introspect_doc = introspect_docs(name=name) 450 except ImportError, e: 451 introspect_error = str(e) 452 if options.must_parse(name): 453 try: 454 parse_doc = parse_docs(name=name) 455 except ParseError, e: 456 parse_error = str(e) 457 except ImportError, e: 458 # If we get here, then there' probably no python source 459 # available; don't bother to generate a warnining. 460 pass 461 462 # Report any errors we encountered. 463 if not suppress_warnings: 464 _report_errors(name, introspect_doc, parse_doc, 465 introspect_error, parse_error) 466 467 # Return the docs we found. 468 return (introspect_doc, parse_doc)
      469
      470 -def _get_docs_from_pyscript(filename, options, progress_estimator):
      471 # [xx] I should be careful about what names I allow as filenames, 472 # and maybe do some munging to prevent problems. 473 474 introspect_doc = parse_doc = None 475 introspect_error = parse_error = None 476 if options.introspect: 477 try: 478 introspect_doc = introspect_docs(filename=filename, is_script=True) 479 if introspect_doc.canonical_name is UNKNOWN: 480 introspect_doc.canonical_name = munge_script_name(filename) 481 except ImportError, e: 482 introspect_error = str(e) 483 if options.parse: 484 try: 485 parse_doc = parse_docs(filename=filename, is_script=True) 486 except ParseError, e: 487 parse_error = str(e) 488 except ImportError, e: 489 parse_error = str(e) 490 491 # Report any errors we encountered. 492 _report_errors(filename, introspect_doc, parse_doc, 493 introspect_error, parse_error) 494 495 # Return the docs we found. 496 return (introspect_doc, parse_doc)
      497
      498 -def _get_docs_from_module_file(filename, options, progress_estimator, 499 parent_docs=(None,None)):
      500 """ 501 Construct and return the API documentation for the python 502 module with the given filename. 503 504 @param parent_docs: The C{ModuleDoc} of the containing package. 505 If C{parent_docs} is not provided, then this method will 506 check if the given filename is contained in a package; and 507 if so, it will construct a stub C{ModuleDoc} for the 508 containing package(s). C{parent_docs} is a tuple, where 509 the first element is the parent from introspection, and 510 the second element is the parent from parsing. 511 """ 512 # Record our progress. 513 modulename = os.path.splitext(os.path.split(filename)[1])[0] 514 if modulename == '__init__': 515 modulename = os.path.split(os.path.split(filename)[0])[1] 516 if parent_docs[0]: 517 modulename = DottedName(parent_docs[0].canonical_name, modulename) 518 elif parent_docs[1]: 519 modulename = DottedName(parent_docs[1].canonical_name, modulename) 520 if options.must_introspect(modulename) or options.must_parse(modulename): 521 log.progress(progress_estimator.progress(), 522 '%s (%s)' % (modulename, filename)) 523 progress_estimator.complete += 1 524 525 # Normalize the filename. 526 filename = os.path.normpath(os.path.abspath(filename)) 527 528 # When possible, use the source version of the file. 529 try: 530 filename = py_src_filename(filename) 531 src_file_available = True 532 except ValueError: 533 src_file_available = False 534 535 # Get the introspected & parsed docs (as appropriate) 536 introspect_doc = parse_doc = None 537 introspect_error = parse_error = None 538 if options.must_introspect(modulename): 539 try: 540 introspect_doc = introspect_docs( 541 filename=filename, context=parent_docs[0]) 542 if introspect_doc.canonical_name is UNKNOWN: 543 introspect_doc.canonical_name = modulename 544 except ImportError, e: 545 introspect_error = str(e) 546 if src_file_available and options.must_parse(modulename): 547 try: 548 parse_doc = parse_docs( 549 filename=filename, context=parent_docs[1]) 550 except ParseError, e: 551 parse_error = str(e) 552 except ImportError, e: 553 parse_error = str(e) 554 555 # Report any errors we encountered. 556 _report_errors(filename, introspect_doc, parse_doc, 557 introspect_error, parse_error) 558 559 # Return the docs we found. 560 return (introspect_doc, parse_doc)
      561
      562 -def _get_docs_from_submodules(item, pkg_docs, options, progress_estimator):
      563 # Extract the package's __path__. 564 if isinstance(pkg_docs[0], ModuleDoc) and pkg_docs[0].is_package: 565 pkg_path = pkg_docs[0].path 566 package_dir = os.path.split(pkg_docs[0].filename)[0] 567 elif isinstance(pkg_docs[1], ModuleDoc) and pkg_docs[1].is_package: 568 pkg_path = pkg_docs[1].path 569 package_dir = os.path.split(pkg_docs[1].filename)[0] 570 else: 571 return [] 572 573 module_filenames = {} 574 subpackage_dirs = set() 575 for subdir in pkg_path: 576 if os.path.isdir(subdir): 577 for name in os.listdir(subdir): 578 filename = os.path.join(subdir, name) 579 # Is it a valid module filename? 580 if is_module_file(filename): 581 basename = os.path.splitext(filename)[0] 582 if os.path.split(basename)[1] != '__init__': 583 module_filenames[basename] = filename 584 # Is it a valid package filename? 585 if is_package_dir(filename): 586 subpackage_dirs.add(filename) 587 588 # Update our estimate of the number of modules in this package. 589 progress_estimator.revise_estimate(item, module_filenames.items(), 590 subpackage_dirs) 591 592 docs = [pkg_docs] 593 for module_filename in module_filenames.values(): 594 d = _get_docs_from_module_file( 595 module_filename, options, progress_estimator, pkg_docs) 596 docs.append(d) 597 for subpackage_dir in subpackage_dirs: 598 subpackage_file = os.path.join(subpackage_dir, '__init__') 599 docs.append(_get_docs_from_module_file( 600 subpackage_file, options, progress_estimator, pkg_docs)) 601 docs += _get_docs_from_submodules( 602 subpackage_dir, docs[-1], options, progress_estimator) 603 return docs
      604
      605 -def _report_errors(name, introspect_doc, parse_doc, 606 introspect_error, parse_error):
      607 hdr = 'In %s:\n' % name 608 if introspect_doc == parse_doc == None: 609 log.start_block('%sNo documentation available!' % hdr) 610 if introspect_error: 611 log.error('Import failed:\n%s' % introspect_error) 612 if parse_error: 613 log.error('Source code parsing failed:\n%s' % parse_error) 614 log.end_block() 615 elif introspect_error: 616 log.start_block('%sImport failed (but source code parsing ' 617 'was successful).' % hdr) 618 log.error(introspect_error) 619 log.end_block() 620 elif parse_error: 621 log.start_block('%sSource code parsing failed (but ' 622 'introspection was successful).' % hdr) 623 log.error(parse_error) 624 log.end_block()
      625 626 627 #///////////////////////////////////////////////////////////////// 628 # Progress Estimation (for Documentation Generation) 629 #///////////////////////////////////////////////////////////////// 630
      631 -class _ProgressEstimator:
      632 """ 633 Used to keep track of progress when generating the initial docs 634 for the given items. (It is not known in advance how many items a 635 package directory will contain, since it might depend on those 636 packages' __path__ values.) 637 """
      638 - def __init__(self, items):
      639 self.est_totals = {} 640 self.complete = 0 641 642 for item in items: 643 if is_package_dir(item): 644 self.est_totals[item] = self._est_pkg_modules(item) 645 else: 646 self.est_totals[item] = 1
      647
      648 - def progress(self):
      649 total = sum(self.est_totals.values()) 650 return float(self.complete) / total
      651
      652 - def revise_estimate(self, pkg_item, modules, subpackages):
      653 del self.est_totals[pkg_item] 654 for item in modules: 655 self.est_totals[item] = 1 656 for item in subpackages: 657 self.est_totals[item] = self._est_pkg_modules(item)
      658
      659 - def _est_pkg_modules(self, package_dir):
      660 num_items = 0 661 662 if is_package_dir(package_dir): 663 for name in os.listdir(package_dir): 664 filename = os.path.join(package_dir, name) 665 if is_module_file(filename): 666 num_items += 1 667 elif is_package_dir(filename): 668 num_items += self._est_pkg_modules(filename) 669 670 return num_items
      671 672 ###################################################################### 673 ## Doc Merger 674 ###################################################################### 675 676 MERGE_PRECEDENCE = { 677 'repr': 'parse', 678 679 # The names we get from introspection match the names that users 680 # can actually use -- i.e., they take magic into account. 681 'canonical_name': 'introspect', 682 683 # Only fall-back on the parser for is_imported if the introspecter 684 # isn't sure. Otherwise, we can end up thinking that vars 685 # containing modules are not imported, which can cause external 686 # modules to show up in the docs (sf bug #1653486) 687 'is_imported': 'introspect', 688 689 # The parser can tell if an assignment creates an alias or not. 690 'is_alias': 'parse', 691 692 # The parser is better able to determine what text file something 693 # came from; e.g., it can't be fooled by 'covert' imports. 694 'docformat': 'parse', 695 696 # The parse should be able to tell definitively whether a module 697 # is a package or not. 698 'is_package': 'parse', 699 700 # Extract the sort spec from the order in which values are defined 701 # in the source file. 702 'sort_spec': 'parse', 703 704 'submodules': 'introspect', 705 706 # The filename used by 'parse' is the source file. 707 'filename': 'parse', 708 709 # 'parse' is more likely to get the encoding right, but 710 # 'introspect' will handle programatically generated docstrings. 711 # Which is better? 712 'docstring': 'introspect', 713 } 714 """Indicates whether information from introspection or parsing should be 715 given precedence, for specific attributes. This dictionary maps from 716 attribute names to either C{'introspect'} or C{'parse'}.""" 717 718 DEFAULT_MERGE_PRECEDENCE = 'introspect' 719 """Indicates whether information from introspection or parsing should be 720 given precedence. Should be either C{'introspect'} or C{'parse'}""" 721 722 _attribute_mergefunc_registry = {}
      723 -def register_attribute_mergefunc(attrib, mergefunc):
      724 """ 725 Register an attribute merge function. This function will be 726 called by L{merge_docs()} when it needs to merge the attribute 727 values of two C{APIDoc}s. 728 729 @param attrib: The name of the attribute whose values are merged 730 by C{mergefunc}. 731 732 @param mergefunc: The merge function, whose sinature is: 733 734 >>> def mergefunc(introspect_val, parse_val, precedence, cyclecheck, path): 735 ... return calculate_merged_value(introspect_val, parse_val) 736 737 Where C{introspect_val} and C{parse_val} are the two values to 738 combine; C{precedence} is a string indicating which value takes 739 precedence for this attribute (C{'introspect'} or C{'parse'}); 740 C{cyclecheck} is a value used by C{merge_docs()} to make sure that 741 it only visits each pair of docs once; and C{path} is a string 742 describing the path that was taken from the root to this 743 attribute (used to generate log messages). 744 745 If the merge function needs to call C{merge_docs}, then it should 746 pass C{cyclecheck} and C{path} back in. (When appropriate, a 747 suffix should be added to C{path} to describe the path taken to 748 the merged values.) 749 """ 750 _attribute_mergefunc_registry[attrib] = mergefunc
      751
      752 -def merge_docs(introspect_doc, parse_doc, cyclecheck=None, path=None):
      753 """ 754 Merge the API documentation information that was obtained from 755 introspection with information that was obtained from parsing. 756 C{introspect_doc} and C{parse_doc} should be two C{APIDoc} instances 757 that describe the same object. C{merge_docs} combines the 758 information from these two instances, and returns the merged 759 C{APIDoc}. 760 761 If C{introspect_doc} and C{parse_doc} are compatible, then they will 762 be I{merged} -- i.e., they will be coerced to a common class, and 763 their state will be stored in a shared dictionary. Once they have 764 been merged, any change made to the attributes of one will affect 765 the other. The value for the each of the merged C{APIDoc}'s 766 attributes is formed by combining the values of the source 767 C{APIDoc}s' attributes, as follows: 768 769 - If either of the source attributes' value is C{UNKNOWN}, then 770 use the other source attribute's value. 771 - Otherwise, if an attribute merge function has been registered 772 for the attribute, then use that function to calculate the 773 merged value from the two source attribute values. 774 - Otherwise, if L{MERGE_PRECEDENCE} is defined for the 775 attribute, then use the attribute value from the source that 776 it indicates. 777 - Otherwise, use the attribute value from the source indicated 778 by L{DEFAULT_MERGE_PRECEDENCE}. 779 780 If C{introspect_doc} and C{parse_doc} are I{not} compatible (e.g., if 781 their values have incompatible types), then C{merge_docs()} will 782 simply return either C{introspect_doc} or C{parse_doc}, depending on 783 the value of L{DEFAULT_MERGE_PRECEDENCE}. The two input 784 C{APIDoc}s will not be merged or modified in any way. 785 786 @param cyclecheck, path: These arguments should only be provided 787 when C{merge_docs()} is called by an attribute merge 788 function. See L{register_attribute_mergefunc()} for more 789 details. 790 """ 791 assert isinstance(introspect_doc, APIDoc) 792 assert isinstance(parse_doc, APIDoc) 793 794 if cyclecheck is None: 795 cyclecheck = set() 796 if introspect_doc.canonical_name not in (None, UNKNOWN): 797 path = '%s' % introspect_doc.canonical_name 798 elif parse_doc.canonical_name not in (None, UNKNOWN): 799 path = '%s' % parse_doc.canonical_name 800 else: 801 path = '??' 802 803 # If we've already examined this pair, then there's nothing 804 # more to do. The reason that we check id's here is that we 805 # want to avoid hashing the APIDoc objects for now, so we can 806 # use APIDoc.merge_and_overwrite() later. 807 if (id(introspect_doc), id(parse_doc)) in cyclecheck: 808 return introspect_doc 809 cyclecheck.add( (id(introspect_doc), id(parse_doc)) ) 810 811 # If these two are already merged, then we're done. (Two 812 # APIDoc's compare equal iff they are identical or have been 813 # merged.) 814 if introspect_doc == parse_doc: 815 return introspect_doc 816 817 # If both values are GenericValueDoc, then we don't want to merge 818 # them. E.g., we don't want to merge 2+2 with 4. So just copy 819 # the parse_doc's parse_repr to introspect_doc, & return it. 820 # (In particular, do *not* call merge_and_overwrite.) 821 if type(introspect_doc) == type(parse_doc) == GenericValueDoc: 822 if parse_doc.parse_repr is not UNKNOWN: 823 introspect_doc.parse_repr = parse_doc.parse_repr 824 introspect_doc.docs_extracted_by = 'both' 825 return introspect_doc 826 827 # Perform several sanity checks here -- if we accidentally 828 # merge values that shouldn't get merged, then bad things can 829 # happen. 830 mismatch = None 831 if (introspect_doc.__class__ != parse_doc.__class__ and 832 not (issubclass(introspect_doc.__class__, parse_doc.__class__) or 833 issubclass(parse_doc.__class__, introspect_doc.__class__))): 834 mismatch = ("value types don't match -- i=%r, p=%r." % 835 (introspect_doc.__class__, parse_doc.__class__)) 836 if (isinstance(introspect_doc, ValueDoc) and 837 isinstance(parse_doc, ValueDoc)): 838 if (introspect_doc.pyval is not UNKNOWN and 839 parse_doc.pyval is not UNKNOWN and 840 introspect_doc.pyval is not parse_doc.pyval): 841 mismatch = "values don't match." 842 elif (introspect_doc.canonical_name not in (None, UNKNOWN) and 843 parse_doc.canonical_name not in (None, UNKNOWN) and 844 introspect_doc.canonical_name != parse_doc.canonical_name): 845 mismatch = "canonical names don't match." 846 if mismatch is not None: 847 log.info("Not merging the parsed & introspected values of %s, " 848 "since their %s" % (path, mismatch)) 849 if DEFAULT_MERGE_PRECEDENCE == 'introspect': 850 return introspect_doc 851 else: 852 return parse_doc 853 854 # If one apidoc's class is a superclass of the other's, then 855 # specialize it to the more specific class. 856 if introspect_doc.__class__ is not parse_doc.__class__: 857 if issubclass(introspect_doc.__class__, parse_doc.__class__): 858 parse_doc.specialize_to(introspect_doc.__class__) 859 if issubclass(parse_doc.__class__, introspect_doc.__class__): 860 introspect_doc.specialize_to(parse_doc.__class__) 861 assert introspect_doc.__class__ is parse_doc.__class__ 862 863 # The posargs and defaults are tied together -- if we merge 864 # the posargs one way, then we need to merge the defaults the 865 # same way. So check them first. (This is a minor hack) 866 if (isinstance(introspect_doc, RoutineDoc) and 867 isinstance(parse_doc, RoutineDoc)): 868 _merge_posargs_and_defaults(introspect_doc, parse_doc, path) 869 870 # Merge the two api_doc's attributes. 871 for attrib in set(introspect_doc.__dict__.keys() + 872 parse_doc.__dict__.keys()): 873 # Be sure not to merge any private attributes (especially 874 # __mergeset or __has_been_hashed!) 875 if attrib.startswith('_'): continue 876 merge_attribute(attrib, introspect_doc, parse_doc, 877 cyclecheck, path) 878 879 # Set the dictionaries to be shared. 880 return introspect_doc.merge_and_overwrite(parse_doc)
      881
      882 -def _merge_posargs_and_defaults(introspect_doc, parse_doc, path):
      883 # If either is unknown, then let merge_attrib handle it. 884 if introspect_doc.posargs is UNKNOWN or parse_doc.posargs is UNKNOWN: 885 return 886 887 # If the introspected doc just has '...', then trust the parsed doc. 888 if introspect_doc.posargs == ['...'] and parse_doc.posargs != ['...']: 889 introspect_doc.posargs = parse_doc.posargs 890 introspect_doc.posarg_defaults = parse_doc.posarg_defaults 891 892 # If they are incompatible, then check the precedence. 893 elif introspect_doc.posargs != parse_doc.posargs: 894 log.info("Not merging the parsed & introspected arg " 895 "lists for %s, since they don't match (%s vs %s)" 896 % (path, introspect_doc.posargs, parse_doc.posargs)) 897 if (MERGE_PRECEDENCE.get('posargs', DEFAULT_MERGE_PRECEDENCE) == 898 'introspect'): 899 parse_doc.posargs = introspect_doc.posargs 900 parse_doc.posarg_defaults = introspect_doc.posarg_defaults 901 else: 902 introspect_doc.posargs = parse_doc.posargs 903 introspect_doc.posarg_defaults = parse_doc.posarg_defaults
      904
      905 -def merge_attribute(attrib, introspect_doc, parse_doc, cyclecheck, path):
      906 precedence = MERGE_PRECEDENCE.get(attrib, DEFAULT_MERGE_PRECEDENCE) 907 if precedence not in ('parse', 'introspect'): 908 raise ValueError('Bad precedence value %r' % precedence) 909 910 if (getattr(introspect_doc, attrib) is UNKNOWN and 911 getattr(parse_doc, attrib) is not UNKNOWN): 912 setattr(introspect_doc, attrib, getattr(parse_doc, attrib)) 913 elif (getattr(introspect_doc, attrib) is not UNKNOWN and 914 getattr(parse_doc, attrib) is UNKNOWN): 915 setattr(parse_doc, attrib, getattr(introspect_doc, attrib)) 916 elif (getattr(introspect_doc, attrib) is UNKNOWN and 917 getattr(parse_doc, attrib) is UNKNOWN): 918 pass 919 else: 920 # Both APIDoc objects have values; we need to merge them. 921 introspect_val = getattr(introspect_doc, attrib) 922 parse_val = getattr(parse_doc, attrib) 923 if attrib in _attribute_mergefunc_registry: 924 handler = _attribute_mergefunc_registry[attrib] 925 merged_val = handler(introspect_val, parse_val, precedence, 926 cyclecheck, path) 927 elif precedence == 'introspect': 928 merged_val = introspect_val 929 elif precedence == 'parse': 930 merged_val = parse_val 931 932 setattr(introspect_doc, attrib, merged_val) 933 setattr(parse_doc, attrib, merged_val)
      934
      935 -def merge_variables(varlist1, varlist2, precedence, cyclecheck, path):
      936 # Merge all variables that are in both sets. 937 for varname, var1 in varlist1.items(): 938 var2 = varlist2.get(varname) 939 if var2 is not None: 940 var = merge_docs(var1, var2, cyclecheck, path+'.'+varname) 941 varlist1[varname] = var 942 varlist2[varname] = var 943 944 # Copy any variables that are not in varlist1 over. 945 for varname, var in varlist2.items(): 946 varlist1.setdefault(varname, var) 947 948 return varlist1
      949
      950 -def merge_value(value1, value2, precedence, cyclecheck, path):
      951 assert value1 is not None and value2 is not None 952 return merge_docs(value1, value2, cyclecheck, path)
      953
      954 -def merge_overrides(v1, v2, precedence, cyclecheck, path):
      955 return merge_value(v1, v2, precedence, cyclecheck, path+'.<overrides>')
      956 -def merge_fget(v1, v2, precedence, cyclecheck, path):
      957 return merge_value(v1, v2, precedence, cyclecheck, path+'.fget')
      958 -def merge_fset(v1, v2, precedence, cyclecheck, path):
      959 return merge_value(v1, v2, precedence, cyclecheck, path+'.fset')
      960 -def merge_fdel(v1, v2, precedence, cyclecheck, path):
      961 return merge_value(v1, v2, precedence, cyclecheck, path+'.fdel')
      962
      963 -def merge_proxy_for(v1, v2, precedence, cyclecheck, path):
      964 # Anything we got from introspection shouldn't have a proxy_for 965 # attribute -- it should be the actual object's documentation. 966 return v1
      967
      968 -def merge_bases(baselist1, baselist2, precedence, cyclecheck, path):
      969 # Be careful here -- if we get it wrong, then we could end up 970 # merging two unrelated classes, which could lead to bad 971 # things (e.g., a class that's its own subclass). So only 972 # merge two bases if we're quite sure they're the same class. 973 # (In particular, if they have the same canonical name.) 974 975 # If the lengths don't match up, then give up. This is most 976 # often caused by __metaclass__. 977 if len(baselist1) != len(baselist2): 978 log.info("Not merging the introspected & parsed base lists " 979 "for %s, since their lengths don't match (%s vs %s)" % 980 (path, len(baselist1), len(baselist2))) 981 if precedence == 'introspect': return baselist1 982 else: return baselist2 983 984 # If any names disagree, then give up. 985 for base1, base2 in zip(baselist1, baselist2): 986 if ((base1.canonical_name not in (None, UNKNOWN) and 987 base2.canonical_name not in (None, UNKNOWN)) and 988 base1.canonical_name != base2.canonical_name): 989 log.info("Not merging the parsed & introspected base " 990 "lists for %s, since the bases' names don't match " 991 "(%s vs %s)" % (path, base1.canonical_name, 992 base2.canonical_name)) 993 if precedence == 'introspect': return baselist1 994 else: return baselist2 995 996 for i, (base1, base2) in enumerate(zip(baselist1, baselist2)): 997 base = merge_docs(base1, base2, cyclecheck, 998 '%s.__bases__[%d]' % (path, i)) 999 baselist1[i] = baselist2[i] = base 1000 1001 return baselist1
      1002
      1003 -def merge_posarg_defaults(defaults1, defaults2, precedence, cyclecheck, path):
      1004 if len(defaults1) != len(defaults2): 1005 if precedence == 'introspect': return defaults1 1006 else: return defaults2 1007 defaults = [] 1008 for i, (d1, d2) in enumerate(zip(defaults1, defaults2)): 1009 if d1 is not None and d2 is not None: 1010 d_path = '%s.<default-arg-val>[%d]' % (path, i) 1011 defaults.append(merge_docs(d1, d2, cyclecheck, d_path)) 1012 elif precedence == 'introspect': 1013 defaults.append(d1) 1014 else: 1015 defaults.append(d2) 1016 return defaults
      1017
      1018 -def merge_docstring(docstring1, docstring2, precedence, cyclecheck, path):
      1019 if docstring1 is None or docstring1 is UNKNOWN or precedence=='parse': 1020 return docstring2 1021 else: 1022 return docstring1
      1023
      1024 -def merge_docs_extracted_by(v1, v2, precedence, cyclecheck, path):
      1025 return 'both'
      1026
      1027 -def merge_submodules(v1, v2, precedence, cyclecheck, path):
      1028 n1 = sorted([m.canonical_name for m in v1]) 1029 n2 = sorted([m.canonical_name for m in v2]) 1030 if (n1 != n2) and (n2 != []): 1031 log.info('Introspector & parser disagree about submodules ' 1032 'for %s: (%s) vs (%s)' % (path, 1033 ', '.join([str(n) for n in n1]), 1034 ', '.join([str(n) for n in n2]))) 1035 return v1 + [m for m in v2 if m.canonical_name not in n1] 1036 1037 return v1
      1038 1039 register_attribute_mergefunc('variables', merge_variables) 1040 register_attribute_mergefunc('value', merge_value) 1041 register_attribute_mergefunc('overrides', merge_overrides) 1042 register_attribute_mergefunc('fget', merge_fget) 1043 register_attribute_mergefunc('fset', merge_fset) 1044 register_attribute_mergefunc('fdel', merge_fdel) 1045 register_attribute_mergefunc('proxy_for', merge_proxy_for) 1046 register_attribute_mergefunc('bases', merge_bases) 1047 register_attribute_mergefunc('posarg_defaults', merge_posarg_defaults) 1048 register_attribute_mergefunc('docstring', merge_docstring) 1049 register_attribute_mergefunc('docs_extracted_by', merge_docs_extracted_by) 1050 register_attribute_mergefunc('submodules', merge_submodules) 1051 1052 ###################################################################### 1053 ## Import Linking 1054 ###################################################################### 1055 1093 1094 ###################################################################### 1095 ## Canonical Name Assignment 1096 ###################################################################### 1097 1098 _name_scores = {} 1099 """A dictionary mapping from each C{ValueDoc} to the score that has 1100 been assigned to its current cannonical name. If 1101 L{assign_canonical_names()} finds a canonical name with a better 1102 score, then it will replace the old name.""" 1103 1104 _unreachable_names = {DottedName(DottedName.UNREACHABLE):1} 1105 """The set of names that have been used for unreachable objects. This 1106 is used to ensure there are no duplicate cannonical names assigned. 1107 C{_unreachable_names} is a dictionary mapping from dotted names to 1108 integer ids, where the next unused unreachable name derived from 1109 dotted name C{n} is 1110 C{DottedName('%s-%s' % (n, str(_unreachable_names[n]+1))}""" 1111
      1112 -def assign_canonical_names(val_doc, name, docindex, score=0):
      1113 """ 1114 Assign a canonical name to C{val_doc} (if it doesn't have one 1115 already), and (recursively) to each variable in C{val_doc}. 1116 In particular, C{val_doc} will be assigned the canonical name 1117 C{name} iff either: 1118 - C{val_doc}'s canonical name is C{UNKNOWN}; or 1119 - C{val_doc}'s current canonical name was assigned by this 1120 method; but the score of the new name (C{score}) is higher 1121 than the score of the current name (C{score_dict[val_doc]}). 1122 1123 Note that canonical names will even be assigned to values 1124 like integers and C{None}; but these should be harmless. 1125 """ 1126 # If we've already visited this node, and our new score 1127 # doesn't beat our old score, then there's nothing more to do. 1128 # Note that since score increases strictly monotonically, this 1129 # also prevents us from going in cycles. 1130 if val_doc in _name_scores and score <= _name_scores[val_doc]: 1131 return 1132 1133 # Update val_doc's canonical name, if appropriate. 1134 if (val_doc not in _name_scores and 1135 val_doc.canonical_name is not UNKNOWN): 1136 # If this is the first time we've seen val_doc, and it 1137 # already has a name, then don't change that name. 1138 _name_scores[val_doc] = sys.maxint 1139 name = val_doc.canonical_name 1140 score = 0 1141 else: 1142 # Otherwise, update the name iff the new score is better 1143 # than the old one. 1144 if (val_doc not in _name_scores or 1145 score > _name_scores[val_doc]): 1146 val_doc.canonical_name = name 1147 _name_scores[val_doc] = score 1148 1149 # Recurse to any contained values. 1150 if isinstance(val_doc, NamespaceDoc): 1151 for var_doc in val_doc.variables.values(): 1152 # Set the variable's canonical name. 1153 varname = DottedName(name, var_doc.name) 1154 var_doc.canonical_name = varname 1155 1156 # If the value is unknown, or is a generic value doc, then 1157 # the valuedoc doesn't get assigned a name; move on. 1158 if (var_doc.value is UNKNOWN 1159 or isinstance(var_doc.value, GenericValueDoc)): 1160 continue 1161 1162 # [XX] After svn commit 1644-1647, I'm not sure if this 1163 # ever gets used: This check is for cases like 1164 # curses.wrapper, where an imported variable shadows its 1165 # value's "real" location. 1166 if _var_shadows_self(var_doc, varname): 1167 _fix_self_shadowing_var(var_doc, varname, docindex) 1168 1169 # Find the score for this new name. 1170 vardoc_score = score-1 1171 if var_doc.is_imported is UNKNOWN: vardoc_score -= 10 1172 elif var_doc.is_imported: vardoc_score -= 100 1173 if var_doc.is_alias is UNKNOWN: vardoc_score -= 10 1174 elif var_doc.is_alias: vardoc_score -= 1000 1175 1176 assign_canonical_names(var_doc.value, varname, 1177 docindex, vardoc_score) 1178 1179 # Recurse to any directly reachable values. 1180 for val_doc_2 in val_doc.apidoc_links(variables=False): 1181 val_name, val_score = _unreachable_name_for(val_doc_2, docindex) 1182 assign_canonical_names(val_doc_2, val_name, docindex, val_score)
      1183
      1184 -def _var_shadows_self(var_doc, varname):
      1185 return (var_doc.value not in (None, UNKNOWN) and 1186 var_doc.value.canonical_name not in (None, UNKNOWN) and 1187 var_doc.value.canonical_name != varname and 1188 varname.dominates(var_doc.value.canonical_name))
      1189
      1190 -def _fix_self_shadowing_var(var_doc, varname, docindex):
      1191 # If possible, find another name for the shadowed value. 1192 cname = var_doc.value.canonical_name 1193 for i in range(1, len(cname)-1): 1194 new_name = cname[:i] + (cname[i]+"'") + cname[i+1:] 1195 val_doc = docindex.get_valdoc(new_name) 1196 if val_doc is not None: 1197 log.warning("%s shadows its own value -- using %s instead" % 1198 (varname, new_name)) 1199 var_doc.value = val_doc 1200 return 1201 1202 # If we couldn't find the actual value, use an unreachable name. 1203 name, score = _unreachable_name_for(var_doc.value, docindex) 1204 log.warning('%s shadows itself -- using %s instead' % (varname, name)) 1205 var_doc.value.canonical_name = name
      1206
      1207 -def _unreachable_name_for(val_doc, docindex):
      1208 assert isinstance(val_doc, ValueDoc) 1209 1210 # [xx] (when) does this help? 1211 if (isinstance(val_doc, ModuleDoc) and 1212 len(val_doc.canonical_name)==1 and val_doc.package is None): 1213 for root_val in docindex.root: 1214 if root_val.canonical_name == val_doc.canonical_name: 1215 if root_val != val_doc: 1216 log.error("Name conflict: %r vs %r" % 1217 (val_doc, root_val)) 1218 break 1219 else: 1220 return val_doc.canonical_name, -1000 1221 1222 # Assign it an 'unreachable' name: 1223 if (val_doc.pyval is not UNKNOWN and 1224 hasattr(val_doc.pyval, '__name__')): 1225 try: 1226 name = DottedName(DottedName.UNREACHABLE, 1227 val_doc.pyval.__name__, strict=True) 1228 except DottedName.InvalidDottedName: 1229 name = DottedName(DottedName.UNREACHABLE) 1230 else: 1231 name = DottedName(DottedName.UNREACHABLE) 1232 1233 # Uniquify the name. 1234 if name in _unreachable_names: 1235 _unreachable_names[name] += 1 1236 name = DottedName('%s-%s' % (name, _unreachable_names[name]-1)) 1237 else: 1238 _unreachable_names[name] = 1 1239 1240 return name, -10000
      1241 1242 ###################################################################### 1243 ## Documentation Inheritance 1244 ###################################################################### 1245
      1246 -def find_overrides(class_doc):
      1247 """ 1248 Set the C{overrides} attribute for all variables in C{class_doc}. 1249 This needs to be done early (before docstring parsing), so we can 1250 know which docstrings to suppress warnings for. 1251 """ 1252 for base_class in list(class_doc.mro(warn_about_bad_bases=True)): 1253 if base_class == class_doc: continue 1254 if base_class.variables is UNKNOWN: continue 1255 for name, var_doc in base_class.variables.items(): 1256 if ( not (name.startswith('__') and not name.endswith('__')) and 1257 base_class == var_doc.container and 1258 name in class_doc.variables and 1259 class_doc.variables[name].container==class_doc and 1260 class_doc.variables[name].overrides is UNKNOWN ): 1261 class_doc.variables[name].overrides = var_doc
      1262 1263
      1264 -def inherit_docs(class_doc):
      1265 for base_class in list(class_doc.mro(warn_about_bad_bases=True)): 1266 if base_class == class_doc: continue 1267 1268 # Inherit any groups. Place them *after* this class's groups, 1269 # so that any groups that are important to this class come 1270 # first. 1271 if base_class.group_specs not in (None, UNKNOWN): 1272 class_doc.group_specs += [gs for gs in base_class.group_specs 1273 if gs not in class_doc.group_specs] 1274 1275 # Inherit any variables. 1276 if base_class.variables is UNKNOWN: continue 1277 for name, var_doc in base_class.variables.items(): 1278 # If it's a __private variable, then don't inherit it. 1279 if name.startswith('__') and not name.endswith('__'): 1280 continue 1281 1282 # Inhetit only from the defining class. Or else, in case of 1283 # multiple inheritance, we may import from a grand-ancestor 1284 # variables overridden by a class that follows in mro. 1285 if base_class != var_doc.container: 1286 continue 1287 1288 # If class_doc doesn't have a variable with this name, 1289 # then inherit it. 1290 if name not in class_doc.variables: 1291 class_doc.variables[name] = var_doc 1292 1293 # Otherwise, class_doc already contains a variable 1294 # that shadows var_doc. But if class_doc's var is 1295 # local, then record the fact that it overrides 1296 # var_doc. 1297 elif class_doc.variables[name].container==class_doc: 1298 class_doc.variables[name].overrides = var_doc 1299 _inherit_info(class_doc.variables[name])
      1300 1301 _INHERITED_ATTRIBS = [ 1302 'descr', 'summary', 'metadata', 'extra_docstring_fields', 1303 'type_descr', 'arg_descrs', 'arg_types', 'return_descr', 1304 'return_type', 'exception_descrs'] 1305 1306 _method_descriptor = type(list.append) 1307
      1308 -def _inherit_info(var_doc):
      1309 """ 1310 Copy any relevant documentation information from the variable that 1311 C{var_doc} overrides into C{var_doc} itself. 1312 """ 1313 src_var = var_doc.overrides 1314 src_val = var_doc.overrides.value 1315 val_doc = var_doc.value 1316 1317 # Special case: if the source value and target values are both c 1318 # extension methods, and the target value's signature is not 1319 # specified, then inherit the source value's signature. 1320 if (isinstance(val_doc, RoutineDoc) and 1321 isinstance(src_val, RoutineDoc) and 1322 (inspect.isbuiltin(val_doc.pyval) or 1323 isinstance(val_doc.pyval, _method_descriptor)) and 1324 (inspect.isbuiltin(src_val.pyval) or 1325 isinstance(src_val.pyval, _method_descriptor)) and 1326 val_doc.all_args() in (['...'], UNKNOWN) and 1327 src_val.all_args() not in (['...'], UNKNOWN)): 1328 for attrib in ['posargs', 'posarg_defaults', 'vararg', 1329 'kwarg', 'return_type']: 1330 setattr(val_doc, attrib, getattr(src_val, attrib)) 1331 1332 # If the new variable has a docstring, then don't inherit 1333 # anything, even if the docstring is blank. 1334 if var_doc.docstring not in (None, UNKNOWN): 1335 return 1336 # [xx] Do I want a check like this:? 1337 # # If it's a method and the signature doesn't match well enough, 1338 # # then give up. 1339 # if (isinstance(src_val, RoutineDoc) and 1340 # isinstance(val_doc, RoutineDoc)): 1341 # if (src_val.posargs != val_doc.posargs[:len(src_val.posargs)] or 1342 # src_val.vararg != None and src_val.vararg != val_doc.vararg): 1343 # log.docstring_warning( 1344 # "The signature of %s does not match the signature of the " 1345 # "method it overrides (%s); not inheriting documentation." % 1346 # (var_doc.canonical_name, src_var.canonical_name)) 1347 # return 1348 1349 # Inherit attributes! 1350 for attrib in _INHERITED_ATTRIBS: 1351 if (hasattr(var_doc, attrib) and hasattr(src_var, attrib) and 1352 getattr(src_var, attrib) not in (None, UNKNOWN)): 1353 setattr(var_doc, attrib, getattr(src_var, attrib)) 1354 elif (src_val is not None and 1355 hasattr(val_doc, attrib) and hasattr(src_val, attrib) and 1356 getattr(src_val, attrib) not in (None, UNKNOWN) and 1357 getattr(val_doc, attrib) in (None, UNKNOWN, [])): 1358 setattr(val_doc, attrib, getattr(src_val, attrib))
      1359

      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink.UrlGenerator.IndexAmbiguous-class.html0000644000175000017500000001532110750103050031437 0ustar pronovicpronovic epydoc.docwriter.xlink.UrlGenerator.IndexAmbiguous
      Package epydoc :: Package docwriter :: Module xlink :: Class UrlGenerator :: Class IndexAmbiguous
      [hide private]
      [frames] | no frames]

      Class IndexAmbiguous

      source code


      The name looked for is ambiguous
      Instance Methods [hide private]

      Inherited from exceptions.Exception: __getitem__, __init__, __str__

      epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.restructuredtext-module.html0000644000175000017500000001160410750103050026660 0ustar pronovicpronovic restructuredtext

      Module restructuredtext


      Classes

      OptimizedReporter
      ParsedRstDocstring
      dotgraph

      Functions

      callgraph_directive
      classtree_directive
      digraph_directive
      importgraph_directive
      latex_head_prefix
      packagetree_directive
      parse_docstring
      python_code_directive
      term_role

      Variables

      CONSOLIDATED_DEFLIST_FIELDS
      CONSOLIDATED_FIELDS

      [hide private] epydoc-3.0.1+dfsg/doc/api/toc-epydoc.util-module.html0000644000175000017500000000474710750103050022711 0ustar pronovicpronovic util

      Module util


      Classes

      RunSubprocessError

      Functions

      decode_with_backslashreplace
      is_module_file
      is_package_dir
      is_pyname
      is_src_filename
      munge_script_name
      plaintext_to_html
      plaintext_to_latex
      py_src_filename
      run_subprocess
      wordwrap

      Variables

      PY_BIN_EXTENSIONS
      PY_SRC_EXTENSIONS

      [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.checker-module.html0000644000175000017500000002643110750103050022547 0ustar pronovicpronovic epydoc.checker
      Package epydoc :: Module checker
      [hide private]
      [frames] | no frames]

      Module checker

      source code

      Documentation completeness checker. This module defines a single class, DocChecker, which can be used to check the that specified classes of objects are documented.

      Classes [hide private]
        DocChecker
      Documentation completeness checker.
      Variables [hide private]
        _NO_DOCS = ['__hash__', '__repr__', '__str__', '__cmp__']
        _NO_BASIC = ['__hash__', '__repr__', '__str__', '__cmp__']
        _NO_RETURN = ['__init__', '__hash__', '__repr__', '__str__', '...
        _NO_PARAM = ['__cmp__']
      Variables Details [hide private]

      _NO_RETURN

      Value:
      ['__init__', '__hash__', '__repr__', '__str__', '__cmp__']
      

      epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.pyval_repr-module.html0000644000175000017500000000360610750103050025406 0ustar pronovicpronovic pyval_repr

      Module pyval_repr


      Classes

      ColorizedPyvalRepr
      PyvalColorizer

      Functions

      colorize_pyval
      is_re_pattern

      [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.ClassDoc-class.html0000644000175000017500000017253210750103050023720 0ustar pronovicpronovic epydoc.apidoc.ClassDoc
      Package epydoc :: Module apidoc :: Class ClassDoc
      [hide private]
      [frames] | no frames]

      Class ClassDoc

      source code


      API documentation information about a single class.

      Instance Methods [hide private]
       
      apidoc_links(self, **filters)
      Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
      source code
      call graph 
       
      is_type(self) source code
      call graph 
       
      is_exception(self) source code
      call graph 
       
      is_newstyle_class(self) source code
      call graph 
       
      mro(self, warn_about_bad_bases=False) source code
      call graph 
       
      _dfs_bases(self, mro, seen, warn_about_bad_bases) source code
      call graph 
       
      _c3_mro(self, warn_about_bad_bases)
      Compute the class precedence list (mro) according to C3.
      source code
      call graph 
       
      _report_bad_base(self, base) source code
       
      _c3_merge(self, seqs)
      Helper function for _c3_mro.
      source code
      call graph 
       
      select_variables(self, group=None, value_type=None, inherited=None, public=None, imported=None, detailed=None)
      Return a specified subset of this class's sorted_variables list.
      source code
      call graph 

      Inherited from NamespaceDoc: __init__, group_names, init_sorted_variables, init_variable_groups, is_detailed, report_unused_groups

      Inherited from NamespaceDoc (private): _init_grouping

      Inherited from ValueDoc: __getstate__, __repr__, __setstate__

      Inherited from APIDoc: __cmp__, __hash__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

      Inherited from APIDoc (private): _debug_setattr

      Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

          Value Representation

      Inherited from ValueDoc: pyval_repr, summary_pyval_repr

      Class Variables [hide private]
          Value Representation

      Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

      Instance Variables [hide private]

      Inherited from ValueDoc: canonical_name, toktree

          Information about Base Classes
      list of ClassDoc bases = _Sentinel('UNKNOWN')
      API documentation for the class's base classes.
          Information about Subclasses
      list of ClassDoc subclasses = _Sentinel('UNKNOWN')
      API documentation for the class's known subclasses.
          Information about Variables

      Inherited from NamespaceDoc: group_specs, sort_spec, sorted_variables, variable_groups, variables

          Value Representation

      Inherited from ValueDoc: parse_repr, pyval

          Context

      Inherited from ValueDoc: defining_module

          Information about Imported Variables

      Inherited from ValueDoc: proxy_for

          Docstrings

      Inherited from APIDoc: docstring, docstring_lineno

          Information Extracted from Docstrings

      Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

          Source Information

      Inherited from APIDoc: docs_extracted_by

      Properties [hide private]

      Inherited from object: __class__

      Method Details [hide private]

      apidoc_links(self, **filters)

      source code 
      call graph 

      Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

      Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

      • imports: Imported variables.
      • packages: Containing packages for modules.
      • submodules: Contained submodules for packages.
      • bases: Bases for classes.
      • subclasses: Subclasses for classes.
      • variables: All variables.
      • private: Private variables.
      • overrides: Points from class variables to the variables they override. This filter is False by default.
      Overrides: APIDoc.apidoc_links
      (inherited documentation)

      _c3_mro(self, warn_about_bad_bases)

      source code 
      call graph 

      Compute the class precedence list (mro) according to C3.

      select_variables(self, group=None, value_type=None, inherited=None, public=None, imported=None, detailed=None)

      source code 
      call graph 

      Return a specified subset of this class's sorted_variables list. If value_type is given, then only return variables whose values have the specified type. If group is given, then only return variables that belong to the specified group. If inherited is True, then only return inherited variables; if inherited is False, then only return local variables.

      Parameters:
      • value_type (string) - A string specifying the value type for which variables should be returned. Valid values are:
        • 'instancemethod' - variables whose values are instance methods.
        • 'classmethod' - variables whose values are class methods.
        • 'staticmethod' - variables whose values are static methods.
        • 'properties' - variables whose values are properties.
        • 'class' - variables whose values are nested classes (including exceptions and types).
        • 'instancevariable' - instance variables. This includes any variables that are explicitly marked as instance variables with docstring fields; and variables with docstrings that are initialized in the constructor.
        • 'classvariable' - class variables. This includes any variables that are not included in any of the above categories.
      • group (string) - The name of the group for which variables should be returned. A complete list of the groups defined by this ClassDoc is available in the group_names instance variable. The first element of this list is always the special group name '', which is used for variables that do not belong to any group.
      • inherited - If None, then return both inherited and local variables; if True, then return only inherited variables; if False, then return only local variables.
      • detailed (bool) - If True (False), return only the variables deserving (not deserving) a detailed informative box. If None, don't care.

      Requires: The sorted_variables and variable_groups attributes must be initialized before this method can be used. See init_sorted_variables() and init_variable_groups().


      epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink.ApiLinkReader-class.html0000644000175000017500000010155210750103050026560 0ustar pronovicpronovic epydoc.docwriter.xlink.ApiLinkReader
      Package epydoc :: Package docwriter :: Module xlink :: Class ApiLinkReader
      [hide private]
      [frames] | no frames]

      Class ApiLinkReader

      source code


      A Docutils standalone reader allowing external documentation links.

      The reader configure the url resolvers at the time read() is invoked the first time.

      Instance Methods [hide private]
       
      __init__(self, *args, **kwargs)
      Initialize the Reader instance.
      source code
      call graph 
       
      read(self, source, parser, settings) source code
      call graph 

      Inherited from docutils.readers.standalone.Reader: get_transforms

      Inherited from docutils.readers.Reader: new_document, parse, set_parser

      Inherited from docutils.Component: supports

      Class Methods [hide private]
       
      read_configuration(self, settings, problematic=True)
      Read the configuration for the configured URL resolver.
      source code
      call graph 
      Class Variables [hide private]
        settings_spec = ('API Linking Options', None, (('Define a new ...
      The option parser configuration.
        _conf = True

      Inherited from docutils.readers.standalone.Reader: config_section, config_section_dependencies, document, supported

      Inherited from docutils.readers.Reader: component_type

      Inherited from docutils.SettingsSpec: relative_path_settings, settings_default_overrides, settings_defaults

      Inherited from docutils.TransformSpec: default_transforms, unknown_reference_resolvers

      Method Details [hide private]

      __init__(self, *args, **kwargs)
      (Constructor)

      source code 
      call graph 

      Initialize the Reader instance.

      Several instance attributes are defined with dummy initial values. Subclasses may use these attributes as they wish.

      Overrides: docutils.readers.Reader.__init__
      (inherited documentation)

      read(self, source, parser, settings)

      source code 
      call graph 
      Overrides: docutils.readers.Reader.read

      read_configuration(self, settings, problematic=True)
      Class Method

      source code 
      call graph 

      Read the configuration for the configured URL resolver.

      Register a new role for each configured API.

      Parameters:
      • settings - the settings structure containing the options to read.
      • problematic (bool) - if True, the registered role will create problematic nodes in case of failed references. If False, a warning will be raised anyway, but the output will appear as an ordinary literal.

      Class Variable Details [hide private]

      settings_spec

      The option parser configuration.
      Value:
      ('API Linking Options',
       None,
       (('Define a new API document.  A new interpreted text role NAME will \
      be added.',
         ['--external-api'],
         {'action': 'append', 'metavar': 'NAME'}),
        ('Use records in FILENAME to resolve objects in the API named NAME.'\
      ,
      ...
      

      epydoc-3.0.1+dfsg/doc/api/epydoc.gui-pysrc.html0000644000175000017500000152746610750103050021621 0ustar pronovicpronovic epydoc.gui
      Package epydoc :: Module gui
      [hide private]
      [frames] | no frames]

      Source Code for Module epydoc.gui

         1  #!/usr/bin/env python 
         2  # 
         3  # objdoc: epydoc command-line interface 
         4  # Edward Loper 
         5  # 
         6  # Created [03/15/02 10:31 PM] 
         7  # $Id: gui.py 646 2004-03-19 19:01:37Z edloper $ 
         8  # 
         9   
        10  """ 
        11  Graphical interface to epydoc.  This interface might be useful for 
        12  systems where it's inconvenient to use the command-line interface 
        13  (such as Windows).  It supports many (but not all) of the features 
        14  that are supported by the command-line interface.  It also supports 
        15  loading and saving of X{project files}, which store a set of related 
        16  modules, and the options that should be used to generate the 
        17  documentation for those modules. 
        18   
        19  Usage:: 
        20      epydocgui [OPTIONS] [FILE.prj | MODULES...] 
        21   
        22      FILE.prj                  An epydoc GUI project file. 
        23      MODULES...                A list of Python modules to document. 
        24      -V, --version             Print the version of epydoc. 
        25      -h, -?, --help, --usage   Display this usage message 
        26      --debug                   Do not suppress error messages 
        27   
        28  @todo: Use ini-style project files, rather than pickles (using the 
        29  same format as the CLI). 
        30  """ 
        31  __docformat__ = 'epytext en' 
        32   
        33  import sys, os.path, re, glob 
        34  from Tkinter import * 
        35  from tkFileDialog import askopenfilename, asksaveasfilename 
        36  from thread import start_new_thread, exit_thread 
        37  from pickle import dump, load 
        38   
        39  # askdirectory is only defined in python 2.2+; fall back on 
        40  # asksaveasfilename if it's not available. 
        41  try: from tkFileDialog import askdirectory 
        42  except: askdirectory = None 
        43   
        44  # Include support for Zope, if it's available. 
        45  try: import ZODB 
        46  except: pass 
        47   
        48  ##///////////////////////////////////////////////////////////////////////// 
        49  ## CONSTANTS 
        50  ##///////////////////////////////////////////////////////////////////////// 
        51   
        52  DEBUG = 0 
        53   
        54  # Colors for tkinter display 
        55  BG_COLOR='#e0e0e0' 
        56  ACTIVEBG_COLOR='#e0e0e0' 
        57  TEXT_COLOR='black' 
        58  ENTRYSELECT_COLOR = ACTIVEBG_COLOR 
        59  SELECT_COLOR = '#208070' 
        60  MESSAGE_COLOR = '#000060' 
        61  ERROR_COLOR = '#600000' 
        62  GUIERROR_COLOR = '#600000' 
        63  WARNING_COLOR = '#604000' 
        64  HEADER_COLOR = '#000000' 
        65   
        66  # Convenience dictionaries for specifying widget colors 
        67  COLOR_CONFIG = {'background':BG_COLOR, 'highlightcolor': BG_COLOR, 
        68                  'foreground':TEXT_COLOR, 'highlightbackground': BG_COLOR} 
        69  ENTRY_CONFIG = {'background':BG_COLOR, 'highlightcolor': BG_COLOR, 
        70                  'foreground':TEXT_COLOR, 'highlightbackground': BG_COLOR, 
        71                  'selectbackground': ENTRYSELECT_COLOR, 
        72                  'selectforeground': TEXT_COLOR} 
        73  SB_CONFIG = {'troughcolor':BG_COLOR, 'activebackground':BG_COLOR, 
        74               'background':BG_COLOR, 'highlightbackground':BG_COLOR} 
        75  LISTBOX_CONFIG = {'highlightcolor': BG_COLOR, 'highlightbackground': BG_COLOR, 
        76                    'foreground':TEXT_COLOR, 'selectforeground': TEXT_COLOR, 
        77                    'selectbackground': ACTIVEBG_COLOR, 'background':BG_COLOR} 
        78  BUTTON_CONFIG = {'background':BG_COLOR, 'highlightthickness':0, 'padx':4,  
        79                   'highlightbackground': BG_COLOR, 'foreground':TEXT_COLOR, 
        80                   'highlightcolor': BG_COLOR, 'activeforeground': TEXT_COLOR, 
        81                   'activebackground': ACTIVEBG_COLOR, 'pady':0} 
        82  CBUTTON_CONFIG = {'background':BG_COLOR, 'highlightthickness':0, 'padx':4,  
        83                    'highlightbackground': BG_COLOR, 'foreground':TEXT_COLOR, 
        84                    'highlightcolor': BG_COLOR, 'activeforeground': TEXT_COLOR, 
        85                    'activebackground': ACTIVEBG_COLOR, 'pady':0, 
        86                    'selectcolor': SELECT_COLOR} 
        87  SHOWMSG_CONFIG = CBUTTON_CONFIG.copy() 
        88  SHOWMSG_CONFIG['foreground'] = MESSAGE_COLOR 
        89  SHOWWRN_CONFIG = CBUTTON_CONFIG.copy() 
        90  SHOWWRN_CONFIG['foreground'] = WARNING_COLOR 
        91  SHOWERR_CONFIG = CBUTTON_CONFIG.copy() 
        92  SHOWERR_CONFIG['foreground'] = ERROR_COLOR 
        93   
        94  # Colors for the progress bar 
        95  PROGRESS_HEIGHT = 16 
        96  PROGRESS_WIDTH = 200 
        97  PROGRESS_BG='#305060' 
        98  PROGRESS_COLOR1 = '#30c070' 
        99  PROGRESS_COLOR2 = '#60ffa0' 
       100  PROGRESS_COLOR3 = '#106030' 
       101   
       102  # On tkinter canvases, where's the zero coordinate? 
       103  if sys.platform.lower().startswith('win'): 
       104      DX = 3; DY = 3 
       105      DH = 0; DW = 7 
       106  else: 
       107      DX = 1; DY = 1 
       108      DH = 1; DW = 3 
       109   
       110  # How much of the progress is in each subtask? 
       111  IMPORT_PROGRESS = 0.1 
       112  BUILD_PROGRESS  = 0.2 
       113  WRITE_PROGRESS  = 1.0 - BUILD_PROGRESS - IMPORT_PROGRESS 
       114   
       115  ##///////////////////////////////////////////////////////////////////////// 
       116  ## IMAGE CONSTANTS 
       117  ##///////////////////////////////////////////////////////////////////////// 
       118   
       119  UP_GIF = '''\ 
       120  R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAAAAAAAAAAA 
       121  AAAAACH5BAEAAAAALAAAAAALAAwAAAQjEMhJKxCW4gzCIJxXZIEwFGDlDadqsii1sq1U0nA64+ON 
       122  5xEAOw== 
       123  ''' 
       124  DOWN_GIF = '''\ 
       125  R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAAAAAAAAAAA 
       126  AAAAACH5BAEAAAAALAAAAAALAAwAAAQmEIQxgLVUCsppsVPngVtXEFfIfWk5nBe4xuSL0tKLy/cu 
       127  7JffJQIAOw== 
       128  ''' 
       129  LEFT_GIF='''\ 
       130  R0lGODlhDAALAKIAANnZ2QDMmQCZZgBmZgAAAAAzM////////yH5BAEAAAAALAAAAAAMAAsAAAM4 
       131  CLocgaCrESiDoBshOAoAgBEyMzgAEIGCowsiOLoLgEBVOLoIqlSFo4OgC1RYM4Ogq1RYg6DLVJgA 
       132  Ow== 
       133  ''' 
       134  RIGHT_GIF='''\ 
       135  R0lGODlhDAALAKIAANnZ2QDMmQBmZgCZZgAzMwAAAP///////yH5BAEAAAAALAAAAAAMAAsAAAM5 
       136  GIGgyzIYgaCrIigTgaALIigyEQiqKLoTgaAoujuDgKJLVAgqIoJEBQAIIkKEhaArRFgIukqFoMsJ 
       137  ADs= 
       138  ''' 
       139   
       140  ##///////////////////////////////////////////////////////////////////////// 
       141  ## MessageIO 
       142  ##///////////////////////////////////////////////////////////////////////// 
       143   
       144  from epydoc import log 
       145  from epydoc.util import wordwrap 
      
      146 -class GUILogger(log.Logger):
      147 _STAGES = [40, 7, 1, 3, 1, 30, 1, 2, 100] 148
      149 - def __init__(self, progress, cancel):
      150 self._progress = progress 151 self._cancel = cancel 152 self.clear()
      153
      154 - def clear(self):
      155 self._messages = [] 156 self._n = 0 157 self._stage = 0 158 self._message_blocks = []
      159
      160 - def log(self, level, message):
      161 message = wordwrap(str(message)).rstrip() + '\n' 162 if self._message_blocks: 163 self._message_blocks[-1][-1].append( (level, message) ) 164 else: 165 self._messages.append( (level, message) )
      166
      167 - def start_block(self, header):
      168 self._message_blocks.append( (header, []) )
      169
      170 - def end_block(self):
      171 header, messages = self._message_blocks.pop() 172 if messages: 173 self._messages.append( ('uline', ' '*75+'\n') ) 174 self.log('header', header) 175 self._messages += messages 176 self._messages.append( ('uline', ' '*75+'\n') )
      177
      178 - def start_progress(self, header=None):
      179 self.log(log.INFO, header) 180 self._stage += 1
      181
      182 - def end_progress(self):
      183 pass
      184
      185 - def progress(self, percent, message=''):
      186 if self._cancel[0]: exit_thread() 187 i = self._stage - 1 188 p = ((sum(self._STAGES[:i]) + percent*self._STAGES[i]) / 189 float(sum(self._STAGES))) 190 self._progress[0] = p
      191
      192 - def read(self):
      193 if self._n >= len(self._messages): 194 return None, None 195 else: 196 self._n += 1 197 return self._messages[self._n-1]
      198 199 ##///////////////////////////////////////////////////////////////////////// 200 ## THREADED DOCUMENTER 201 ##///////////////////////////////////////////////////////////////////////// 202
      203 -def document(options, cancel, done):
      204 """ 205 Create the documentation for C{modules}, using the options 206 specified by C{options}. C{document} is designed to be started in 207 its own thread by L{EpydocGUI._go}. 208 209 @param options: The options to use for generating documentation. 210 This includes keyword options that can be given to 211 L{docwriter.html.HTMLWriter}, as well as the option C{target}, which 212 controls where the output is written to. 213 @type options: C{dictionary} 214 """ 215 from epydoc.docwriter.html import HTMLWriter 216 from epydoc.docbuilder import build_doc_index 217 import epydoc.docstringparser 218 219 # Set the default docformat. 220 docformat = options.get('docformat', 'epytext') 221 epydoc.docstringparser.DEFAULT_DOCFORMAT = docformat 222 223 try: 224 parse = options['introspect_or_parse'] in ('parse', 'both') 225 introspect = options['introspect_or_parse'] in ('introspect', 'both') 226 docindex = build_doc_index(options['modules'], parse, introspect) 227 html_writer = HTMLWriter(docindex, **options) 228 log.start_progress('Writing HTML docs to %r' % options['target']) 229 html_writer.write(options['target']) 230 log.end_progress() 231 232 # We're done. 233 log.warning('Finished!') 234 done[0] = 'done' 235 236 except SystemExit: 237 # Cancel. 238 log.error('Cancelled!') 239 done[0] ='cancel' 240 raise 241 except Exception, e: 242 # We failed. 243 log.error('Internal error: %s' % e) 244 done[0] ='cancel' 245 raise 246 except: 247 # We failed. 248 log.error('Internal error!') 249 done[0] ='cancel' 250 raise
      251 252 ##///////////////////////////////////////////////////////////////////////// 253 ## GUI 254 ##///////////////////////////////////////////////////////////////////////// 255
      256 -class EpydocGUI:
      257 """ 258 A graphical user interace to epydoc. 259 """
      260 - def __init__(self):
      261 self._afterid = 0 262 self._progress = [None] 263 self._cancel = [0] 264 self._filename = None 265 self._init_dir = None 266 267 # Store a copy of sys.modules, so that we can restore it 268 # later. This is useful for making sure that we reload 269 # everything when we re-build its documentation. This will 270 # *not* reload the modules that are present when the EpydocGUI 271 # is created, but that should only contain some builtins, some 272 # epydoc modules, Tkinter, pickle, and thread.. 273 self._old_modules = sys.modules.keys() 274 275 # Create the main window. 276 self._root = Tk() 277 self._root['background']=BG_COLOR 278 self._root.bind('<Control-q>', self.destroy) 279 self._root.bind('<Alt-q>', self.destroy) 280 self._root.bind('<Alt-x>', self.destroy) 281 self._root.bind('<Control-x>', self.destroy) 282 #self._root.bind('<Control-d>', self.destroy) 283 self._root.title('Epydoc') 284 self._rootframe = Frame(self._root, background=BG_COLOR, 285 border=2, relief='raised') 286 self._rootframe.pack(expand=1, fill='both', padx=2, pady=2) 287 288 # Set up the basic frames. Do not pack the options frame or 289 # the messages frame; the GUI has buttons to expand them. 290 leftframe = Frame(self._rootframe, background=BG_COLOR) 291 leftframe.pack(expand=1, fill='both', side='left') 292 optsframe = Frame(self._rootframe, background=BG_COLOR) 293 mainframe = Frame(leftframe, background=BG_COLOR) 294 mainframe.pack(expand=1, fill='both', side='top') 295 ctrlframe = Frame(mainframe, background=BG_COLOR) 296 ctrlframe.pack(side="bottom", fill='x', expand=0) 297 msgsframe = Frame(leftframe, background=BG_COLOR) 298 299 self._optsframe = optsframe 300 self._msgsframe = msgsframe 301 302 # Initialize all the frames, etc. 303 self._init_menubar() 304 self._init_progress_bar(mainframe) 305 self._init_module_list(mainframe) 306 self._init_options(optsframe, ctrlframe) 307 self._init_messages(msgsframe, ctrlframe) 308 self._init_bindings() 309 310 # Set up logging 311 self._logger = GUILogger(self._progress, self._cancel) 312 log.register_logger(self._logger) 313 314 # Open the messages pane by default. 315 self._messages_toggle()
      316 317 ## For testing options: 318 #self._options_toggle() 319
      320 - def _init_menubar(self):
      321 menubar = Menu(self._root, borderwidth=2, 322 background=BG_COLOR, 323 activebackground=BG_COLOR) 324 filemenu = Menu(menubar, tearoff=0) 325 filemenu.add_command(label='New Project', underline=0, 326 command=self._new, 327 accelerator='Ctrl-n') 328 filemenu.add_command(label='Open Project', underline=0, 329 command=self._open, 330 accelerator='Ctrl-o') 331 filemenu.add_command(label='Save Project', underline=0, 332 command=self._save, 333 accelerator='Ctrl-s') 334 filemenu.add_command(label='Save As..', underline=5, 335 command=self._saveas, 336 accelerator='Ctrl-a') 337 filemenu.add_separator() 338 filemenu.add_command(label='Exit', underline=1, 339 command=self.destroy, 340 accelerator='Ctrl-x') 341 menubar.add_cascade(label='File', underline=0, menu=filemenu) 342 gomenu = Menu(menubar, tearoff=0) 343 gomenu.add_command(label='Run Epydoc', command=self._open, 344 underline=0, accelerator='Alt-g') 345 menubar.add_cascade(label='Run', menu=gomenu, underline=0) 346 self._root.config(menu=menubar)
      347
      348 - def _init_module_list(self, mainframe):
      349 mframe1 = Frame(mainframe, relief='groove', border=2, 350 background=BG_COLOR) 351 mframe1.pack(side="top", fill='both', expand=1, padx=4, pady=3) 352 l = Label(mframe1, text="Modules to document:", 353 justify='left', **COLOR_CONFIG) 354 l.pack(side='top', fill='none', anchor='nw', expand=0) 355 mframe2 = Frame(mframe1, background=BG_COLOR) 356 mframe2.pack(side="top", fill='both', expand=1) 357 mframe3 = Frame(mframe1, background=BG_COLOR) 358 mframe3.pack(side="bottom", fill='x', expand=0) 359 self._module_list = Listbox(mframe2, width=80, height=10, 360 selectmode='multiple', 361 **LISTBOX_CONFIG) 362 self._module_list.pack(side="left", fill='both', expand=1) 363 sb = Scrollbar(mframe2, orient='vertical',**SB_CONFIG) 364 sb['command']=self._module_list.yview 365 sb.pack(side='right', fill='y') 366 self._module_list.config(yscrollcommand=sb.set) 367 Label(mframe3, text="Add:", **COLOR_CONFIG).pack(side='left') 368 self._module_entry = Entry(mframe3, **ENTRY_CONFIG) 369 self._module_entry.pack(side='left', fill='x', expand=1) 370 self._module_entry.bind('<Return>', self._entry_module) 371 self._module_delete = Button(mframe3, text="Remove", 372 command=self._delete_module, 373 **BUTTON_CONFIG) 374 self._module_delete.pack(side='right', expand=0, padx=2) 375 self._module_browse = Button(mframe3, text="Browse", 376 command=self._browse_module, 377 **BUTTON_CONFIG) 378 self._module_browse.pack(side='right', expand=0, padx=2)
      379
      380 - def _init_progress_bar(self, mainframe):
      381 pframe1 = Frame(mainframe, background=BG_COLOR) 382 pframe1.pack(side="bottom", fill='x', expand=0) 383 self._go_button = Button(pframe1, width=4, text='Start', 384 underline=0, command=self._go, 385 **BUTTON_CONFIG) 386 self._go_button.pack(side='left', padx=4) 387 pframe2 = Frame(pframe1, relief='groove', border=2, 388 background=BG_COLOR) 389 pframe2.pack(side="top", fill='x', expand=1, padx=4, pady=3) 390 Label(pframe2, text='Progress:', **COLOR_CONFIG).pack(side='left') 391 H = self._H = PROGRESS_HEIGHT 392 W = self._W = PROGRESS_WIDTH 393 c = self._canvas = Canvas(pframe2, height=H+DH, width=W+DW, 394 background=PROGRESS_BG, border=0, 395 selectborderwidth=0, relief='sunken', 396 insertwidth=0, insertborderwidth=0, 397 highlightbackground=BG_COLOR) 398 self._canvas.pack(side='left', fill='x', expand=1, padx=4) 399 self._r2 = c.create_rectangle(0,0,0,0, outline=PROGRESS_COLOR2) 400 self._r3 = c.create_rectangle(0,0,0,0, outline=PROGRESS_COLOR3) 401 self._r1 = c.create_rectangle(0,0,0,0, fill=PROGRESS_COLOR1, 402 outline='') 403 self._canvas.bind('<Configure>', self._configure)
      404
      405 - def _init_messages(self, msgsframe, ctrlframe):
      406 self._downImage = PhotoImage(master=self._root, data=DOWN_GIF) 407 self._upImage = PhotoImage(master=self._root, data=UP_GIF) 408 409 # Set up the messages control frame 410 b1 = Button(ctrlframe, text="Messages", justify='center', 411 command=self._messages_toggle, underline=0, 412 highlightthickness=0, activebackground=BG_COLOR, 413 border=0, relief='flat', padx=2, pady=0, **COLOR_CONFIG) 414 b2 = Button(ctrlframe, image=self._downImage, relief='flat', 415 border=0, command=self._messages_toggle, 416 activebackground=BG_COLOR, **COLOR_CONFIG) 417 self._message_button = b2 418 self._messages_visible = 0 419 b2.pack(side="left") 420 b1.pack(side="left") 421 422 f = Frame(msgsframe, background=BG_COLOR) 423 f.pack(side='top', expand=1, fill='both') 424 messages = Text(f, width=80, height=10, **ENTRY_CONFIG) 425 messages['state'] = 'disabled' 426 messages.pack(fill='both', expand=1, side='left') 427 self._messages = messages 428 429 # Add a scrollbar 430 sb = Scrollbar(f, orient='vertical', **SB_CONFIG) 431 sb.pack(fill='y', side='right') 432 sb['command'] = messages.yview 433 messages['yscrollcommand'] = sb.set 434 435 # Set up some colorization tags 436 messages.tag_config('error', foreground=ERROR_COLOR) 437 messages.tag_config('warning', foreground=WARNING_COLOR) 438 messages.tag_config('guierror', foreground=GUIERROR_COLOR) 439 messages.tag_config('message', foreground=MESSAGE_COLOR) 440 messages.tag_config('header', foreground=HEADER_COLOR) 441 messages.tag_config('uline', underline=1) 442 443 # Keep track of tag state.. 444 self._in_header = 0 445 self._last_tag = 'error' 446 447 # Add some buttons 448 buttons = Frame(msgsframe, background=BG_COLOR) 449 buttons.pack(side='bottom', fill='x') 450 self._show_errors = IntVar(self._root) 451 self._show_errors.set(1) 452 self._show_warnings = IntVar(self._root) 453 self._show_warnings.set(1) 454 self._show_messages = IntVar(self._root) 455 self._show_messages.set(0) 456 Checkbutton(buttons, text='Show Messages', var=self._show_messages, 457 command=self._update_msg_tags, 458 **SHOWMSG_CONFIG).pack(side='left') 459 Checkbutton(buttons, text='Show Warnings', var=self._show_warnings, 460 command=self._update_msg_tags, 461 **SHOWWRN_CONFIG).pack(side='left') 462 Checkbutton(buttons, text='Show Errors', var=self._show_errors, 463 command=self._update_msg_tags, 464 **SHOWERR_CONFIG).pack(side='left') 465 self._update_msg_tags()
      466
      467 - def _update_msg_tags(self, *e):
      468 elide_errors = not self._show_errors.get() 469 elide_warnings = not self._show_warnings.get() 470 elide_messages = not self._show_messages.get() 471 elide_headers = elide_errors and elide_warnings 472 self._messages.tag_config('error', elide=elide_errors) 473 self._messages.tag_config('guierror', elide=elide_errors) 474 self._messages.tag_config('warning', elide=elide_warnings) 475 self._messages.tag_config('message', elide=elide_messages) 476 self._messages.tag_config('header', elide=elide_headers)
      477
      478 - def _init_options(self, optsframe, ctrlframe):
      479 self._leftImage=PhotoImage(master=self._root, data=LEFT_GIF) 480 self._rightImage=PhotoImage(master=self._root, data=RIGHT_GIF) 481 482 # Set up the options control frame 483 b1 = Button(ctrlframe, text="Options", justify='center', 484 border=0, relief='flat', 485 command=self._options_toggle, padx=2, 486 underline=0, pady=0, highlightthickness=0, 487 activebackground=BG_COLOR, **COLOR_CONFIG) 488 b2 = Button(ctrlframe, image=self._rightImage, relief='flat', 489 border=0, command=self._options_toggle, 490 activebackground=BG_COLOR, **COLOR_CONFIG) 491 self._option_button = b2 492 self._options_visible = 0 493 b2.pack(side="right") 494 b1.pack(side="right") 495 496 oframe2 = Frame(optsframe, relief='groove', border=2, 497 background=BG_COLOR) 498 oframe2.pack(side="right", fill='both', 499 expand=0, padx=4, pady=3, ipadx=4) 500 501 Label(oframe2, text="Project Options", font='helvetica -16', 502 **COLOR_CONFIG).pack(anchor='w') 503 oframe3 = Frame(oframe2, background=BG_COLOR) 504 oframe3.pack(fill='x') 505 oframe4 = Frame(oframe2, background=BG_COLOR) 506 oframe4.pack(fill='x') 507 oframe7 = Frame(oframe2, background=BG_COLOR) 508 oframe7.pack(fill='x') 509 div = Frame(oframe2, background=BG_COLOR, border=1, relief='sunk') 510 div.pack(ipady=1, fill='x', padx=4, pady=2) 511 512 Label(oframe2, text="Help File", font='helvetica -16', 513 **COLOR_CONFIG).pack(anchor='w') 514 oframe5 = Frame(oframe2, background=BG_COLOR) 515 oframe5.pack(fill='x') 516 div = Frame(oframe2, background=BG_COLOR, border=1, relief='sunk') 517 div.pack(ipady=1, fill='x', padx=4, pady=2) 518 519 Label(oframe2, text="CSS Stylesheet", font='helvetica -16', 520 **COLOR_CONFIG).pack(anchor='w') 521 oframe6 = Frame(oframe2, background=BG_COLOR) 522 oframe6.pack(fill='x') 523 524 #==================== oframe3 ==================== 525 # -n NAME, --name NAME 526 row = 0 527 l = Label(oframe3, text="Project Name:", **COLOR_CONFIG) 528 l.grid(row=row, column=0, sticky='e') 529 self._name_entry = Entry(oframe3, **ENTRY_CONFIG) 530 self._name_entry.grid(row=row, column=1, sticky='ew', columnspan=3) 531 532 # -u URL, --url URL 533 row += 1 534 l = Label(oframe3, text="Project URL:", **COLOR_CONFIG) 535 l.grid(row=row, column=0, sticky='e') 536 self._url_entry = Entry(oframe3, **ENTRY_CONFIG) 537 self._url_entry.grid(row=row, column=1, sticky='ew', columnspan=3) 538 539 # -o DIR, --output DIR 540 row += 1 541 l = Label(oframe3, text="Output Directory:", **COLOR_CONFIG) 542 l.grid(row=row, column=0, sticky='e') 543 self._out_entry = Entry(oframe3, **ENTRY_CONFIG) 544 self._out_entry.grid(row=row, column=1, sticky='ew', columnspan=2) 545 self._out_browse = Button(oframe3, text="Browse", 546 command=self._browse_out, 547 **BUTTON_CONFIG) 548 self._out_browse.grid(row=row, column=3, sticky='ew', padx=2) 549 550 #==================== oframe4 ==================== 551 # --no-frames 552 row = 0 553 self._frames_var = IntVar(self._root) 554 self._frames_var.set(1) 555 l = Label(oframe4, text="Generate a frame-based table of contents", 556 **COLOR_CONFIG) 557 l.grid(row=row, column=1, sticky='w') 558 cb = Checkbutton(oframe4, var=self._frames_var, **CBUTTON_CONFIG) 559 cb.grid(row=row, column=0, sticky='e') 560 561 # --no-private 562 row += 1 563 self._private_var = IntVar(self._root) 564 self._private_var.set(1) 565 l = Label(oframe4, text="Generate documentation for private objects", 566 **COLOR_CONFIG) 567 l.grid(row=row, column=1, sticky='w') 568 cb = Checkbutton(oframe4, var=self._private_var, **CBUTTON_CONFIG) 569 cb.grid(row=row, column=0, sticky='e') 570 571 # --show-imports 572 row += 1 573 self._imports_var = IntVar(self._root) 574 self._imports_var.set(0) 575 l = Label(oframe4, text="List imported classes and functions", 576 **COLOR_CONFIG) 577 l.grid(row=row, column=1, sticky='w') 578 cb = Checkbutton(oframe4, var=self._imports_var, **CBUTTON_CONFIG) 579 cb.grid(row=row, column=0, sticky='e') 580 581 #==================== oframe7 ==================== 582 # --docformat 583 row += 1 584 l = Label(oframe7, text="Default Docformat:", **COLOR_CONFIG) 585 l.grid(row=row, column=0, sticky='e') 586 df_var = self._docformat_var = StringVar(self._root) 587 self._docformat_var.set('epytext') 588 b = Radiobutton(oframe7, var=df_var, text='Epytext', 589 value='epytext', **CBUTTON_CONFIG) 590 b.grid(row=row, column=1, sticky='w') 591 b = Radiobutton(oframe7, var=df_var, text='ReStructuredText', 592 value='restructuredtext', **CBUTTON_CONFIG) 593 b.grid(row=row, column=2, columnspan=2, sticky='w') 594 row += 1 595 b = Radiobutton(oframe7, var=df_var, text='Plaintext', 596 value='plaintext', **CBUTTON_CONFIG) 597 b.grid(row=row, column=1, sticky='w') 598 b = Radiobutton(oframe7, var=df_var, text='Javadoc', 599 value='javadoc', **CBUTTON_CONFIG) 600 b.grid(row=row, column=2, columnspan=2, sticky='w') 601 row += 1 602 603 # Separater 604 Frame(oframe7, background=BG_COLOR).grid(row=row, column=1, pady=3) 605 row += 1 606 607 # --inheritance 608 l = Label(oframe7, text="Inheritance Style:", **COLOR_CONFIG) 609 l.grid(row=row, column=0, sticky='e') 610 inh_var = self._inheritance_var = StringVar(self._root) 611 self._inheritance_var.set('grouped') 612 b = Radiobutton(oframe7, var=inh_var, text='Grouped', 613 value='grouped', **CBUTTON_CONFIG) 614 b.grid(row=row, column=1, sticky='w') 615 b = Radiobutton(oframe7, var=inh_var, text='Listed', 616 value='listed', **CBUTTON_CONFIG) 617 b.grid(row=row, column=2, sticky='w') 618 b = Radiobutton(oframe7, var=inh_var, text='Included', 619 value='included', **CBUTTON_CONFIG) 620 b.grid(row=row, column=3, sticky='w') 621 row += 1 622 623 # Separater 624 Frame(oframe7, background=BG_COLOR).grid(row=row, column=1, pady=3) 625 row += 1 626 627 # --parse-only, --introspect-only 628 l = Label(oframe7, text="Get docs from:", **COLOR_CONFIG) 629 l.grid(row=row, column=0, sticky='e') 630 iop_var = self._introspect_or_parse_var = StringVar(self._root) 631 self._introspect_or_parse_var.set('both') 632 b = Radiobutton(oframe7, var=iop_var, text='Parsing', 633 value='parse', **CBUTTON_CONFIG) 634 b.grid(row=row, column=1, sticky='w') 635 b = Radiobutton(oframe7, var=iop_var, text='Introspecting', 636 value='introspect', **CBUTTON_CONFIG) 637 b.grid(row=row, column=2, sticky='w') 638 b = Radiobutton(oframe7, var=iop_var, text='Both', 639 value='both', **CBUTTON_CONFIG) 640 b.grid(row=row, column=3, sticky='w') 641 row += 1 642 643 #==================== oframe5 ==================== 644 # --help-file FILE 645 row = 0 646 self._help_var = StringVar(self._root) 647 self._help_var.set('default') 648 b = Radiobutton(oframe5, var=self._help_var, 649 text='Default', 650 value='default', **CBUTTON_CONFIG) 651 b.grid(row=row, column=1, sticky='w') 652 row += 1 653 b = Radiobutton(oframe5, var=self._help_var, 654 text='Select File', 655 value='-other-', **CBUTTON_CONFIG) 656 b.grid(row=row, column=1, sticky='w') 657 self._help_entry = Entry(oframe5, **ENTRY_CONFIG) 658 self._help_entry.grid(row=row, column=2, sticky='ew') 659 self._help_browse = Button(oframe5, text='Browse', 660 command=self._browse_help, 661 **BUTTON_CONFIG) 662 self._help_browse.grid(row=row, column=3, sticky='ew', padx=2) 663 664 from epydoc.docwriter.html_css import STYLESHEETS 665 items = STYLESHEETS.items() 666 def _css_sort(css1, css2): 667 if css1[0] == 'default': return -1 668 elif css2[0] == 'default': return 1 669 else: return cmp(css1[0], css2[0])
      670 items.sort(_css_sort) 671 672 #==================== oframe6 ==================== 673 # -c CSS, --css CSS 674 # --private-css CSS 675 row = 0 676 #l = Label(oframe6, text="Public", **COLOR_CONFIG) 677 #l.grid(row=row, column=0, sticky='e') 678 #l = Label(oframe6, text="Private", **COLOR_CONFIG) 679 #l.grid(row=row, column=1, sticky='w') 680 row += 1 681 css_var = self._css_var = StringVar(self._root) 682 css_var.set('default') 683 #private_css_var = self._private_css_var = StringVar(self._root) 684 #private_css_var.set('default') 685 for (name, (sheet, descr)) in items: 686 b = Radiobutton(oframe6, var=css_var, value=name, **CBUTTON_CONFIG) 687 b.grid(row=row, column=0, sticky='e') 688 #b = Radiobutton(oframe6, var=private_css_var, value=name, 689 # text=name, **CBUTTON_CONFIG) 690 #b.grid(row=row, column=1, sticky='w') 691 l = Label(oframe6, text=descr, **COLOR_CONFIG) 692 l.grid(row=row, column=1, sticky='w') 693 row += 1 694 b = Radiobutton(oframe6, var=css_var, value='-other-', 695 **CBUTTON_CONFIG) 696 b.grid(row=row, column=0, sticky='e') 697 #b = Radiobutton(oframe6, text='Select File', var=private_css_var, 698 # value='-other-', **CBUTTON_CONFIG) 699 #b.grid(row=row, column=1, sticky='w') 700 #l = Label(oframe6, text='Select File', **COLOR_CONFIG) 701 #l.grid(row=row, column=1, sticky='w') 702 self._css_entry = Entry(oframe6, **ENTRY_CONFIG) 703 self._css_entry.grid(row=row, column=1, sticky='ew') 704 self._css_browse = Button(oframe6, text="Browse", 705 command=self._browse_css, 706 **BUTTON_CONFIG) 707 self._css_browse.grid(row=row, column=2, sticky='ew', padx=2)
      708
      709 - def _init_bindings(self):
      710 self._root.bind('<Delete>', self._delete_module) 711 self._root.bind('<Alt-o>', self._options_toggle) 712 self._root.bind('<Alt-m>', self._messages_toggle) 713 self._root.bind('<F5>', self._go) 714 self._root.bind('<Alt-s>', self._go) 715 716 self._root.bind('<Control-n>', self._new) 717 self._root.bind('<Control-o>', self._open) 718 self._root.bind('<Control-s>', self._save) 719 self._root.bind('<Control-a>', self._saveas)
      720
      721 - def _options_toggle(self, *e):
      722 if self._options_visible: 723 self._optsframe.forget() 724 self._option_button['image'] = self._rightImage 725 self._options_visible = 0 726 else: 727 self._optsframe.pack(fill='both', side='right') 728 self._option_button['image'] = self._leftImage 729 self._options_visible = 1
      730
      731 - def _messages_toggle(self, *e):
      732 if self._messages_visible: 733 self._msgsframe.forget() 734 self._message_button['image'] = self._rightImage 735 self._messages_visible = 0 736 else: 737 self._msgsframe.pack(fill='both', side='bottom', expand=1) 738 self._message_button['image'] = self._leftImage 739 self._messages_visible = 1
      740
      741 - def _configure(self, event):
      742 self._W = event.width-DW
      743
      744 - def _delete_module(self, *e):
      745 selection = self._module_list.curselection() 746 if len(selection) != 1: return 747 self._module_list.delete(selection[0])
      748
      749 - def _entry_module(self, *e):
      750 modules = [self._module_entry.get()] 751 if glob.has_magic(modules[0]): 752 modules = glob.glob(modules[0]) 753 for name in modules: 754 self.add_module(name, check=1) 755 self._module_entry.delete(0, 'end')
      756
      757 - def _browse_module(self, *e):
      758 title = 'Select a module for documentation' 759 ftypes = [('Python module', '.py'), 760 ('Python extension', '.so'), 761 ('All files', '*')] 762 filename = askopenfilename(filetypes=ftypes, title=title, 763 defaultextension='.py', 764 initialdir=self._init_dir) 765 if not filename: return 766 self._init_dir = os.path.dirname(filename) 767 self.add_module(filename, check=1)
      768
      769 - def _browse_css(self, *e):
      770 title = 'Select a CSS stylesheet' 771 ftypes = [('CSS Stylesheet', '.css'), ('All files', '*')] 772 filename = askopenfilename(filetypes=ftypes, title=title, 773 defaultextension='.css') 774 if not filename: return 775 self._css_entry.delete(0, 'end') 776 self._css_entry.insert(0, filename)
      777
      778 - def _browse_help(self, *e):
      779 title = 'Select a help file' 780 self._help_var.set('-other-') 781 ftypes = [('HTML file', '.html'), ('All files', '*')] 782 filename = askopenfilename(filetypes=ftypes, title=title, 783 defaultextension='.html') 784 if not filename: return 785 self._help_entry.delete(0, 'end') 786 self._help_entry.insert(0, filename)
      787
      788 - def _browse_out(self, *e):
      789 ftypes = [('All files', '*')] 790 title = 'Choose the output directory' 791 if askdirectory is not None: 792 filename = askdirectory(mustexist=0, title=title) 793 if not filename: return 794 else: 795 # Hack for Python 2.1 or earlier: 796 filename = asksaveasfilename(filetypes=ftypes, title=title, 797 initialfile='--this directory--') 798 if not filename: return 799 (f1, f2) = os.path.split(filename) 800 if f2 == '--this directory--': filename = f1 801 self._out_entry.delete(0, 'end') 802 self._out_entry.insert(0, filename)
      803
      804 - def destroy(self, *e):
      805 if self._root is None: return 806 807 # Unload any modules that we've imported 808 for m in sys.modules.keys(): 809 if m not in self._old_modules: del sys.modules[m] 810 self._root.destroy() 811 self._root = None
      812
      813 - def add_module(self, name, check=0):
      814 from epydoc.util import is_package_dir, is_pyname, is_module_file 815 from epydoc.docintrospecter import get_value_from_name 816 from epydoc.docintrospecter import get_value_from_filename 817 818 if (os.path.isfile(name) or is_package_dir(name) or is_pyname(name)): 819 # Check that it's a good module, if requested. 820 if check: 821 try: 822 if is_module_file(name) or is_package_dir(name): 823 get_value_from_filename(name) 824 elif os.path.isfile(name): 825 get_value_from_scriptname(name) 826 else: 827 get_value_from_name(name) 828 except ImportError, e: 829 log.error(e) 830 self._update_messages() 831 self._root.bell() 832 return 833 834 # Add the module to the list of modules. 835 self._module_list.insert('end', name) 836 self._module_list.yview('end') 837 else: 838 log.error("Couldn't find %r" % name) 839 self._update_messages() 840 self._root.bell()
      841
      842 - def mainloop(self, *args, **kwargs):
      843 self._root.mainloop(*args, **kwargs)
      844
      845 - def _getopts(self):
      846 options = {} 847 options['modules'] = self._module_list.get(0, 'end') 848 options['prj_name'] = self._name_entry.get() or '' 849 options['prj_url'] = self._url_entry.get() or None 850 options['docformat'] = self._docformat_var.get() 851 options['inheritance'] = self._inheritance_var.get() 852 options['introspect_or_parse'] = self._introspect_or_parse_var.get() 853 options['target'] = self._out_entry.get() or 'html' 854 options['frames'] = self._frames_var.get() 855 options['private'] = self._private_var.get() 856 options['show_imports'] = self._imports_var.get() 857 if self._help_var.get() == '-other-': 858 options['help'] = self._help_entry.get() or None 859 else: 860 options['help'] = None 861 if self._css_var.get() == '-other-': 862 options['css'] = self._css_entry.get() or 'default' 863 else: 864 options['css'] = self._css_var.get() or 'default' 865 #if self._private_css_var.get() == '-other-': 866 # options['private_css'] = self._css_entry.get() or 'default' 867 #else: 868 # options['private_css'] = self._private_css_var.get() or 'default' 869 return options
      870
      871 - def _go(self, *e):
      872 if len(self._module_list.get(0,'end')) == 0: 873 self._root.bell() 874 return 875 876 if self._progress[0] != None: 877 self._cancel[0] = 1 878 return 879 880 # Construct the argument list for document(). 881 opts = self._getopts() 882 self._progress[0] = 0.0 883 self._cancel[0] = 0 884 args = (opts, self._cancel, self._progress) 885 886 # Clear the messages window. 887 self._messages['state'] = 'normal' 888 self._messages.delete('0.0', 'end') 889 self._messages['state'] = 'disabled' 890 self._logger.clear() 891 892 # Restore the module list. This will force re-loading of 893 # anything that we're documenting. 894 for m in sys.modules.keys(): 895 if m not in self._old_modules: 896 del sys.modules[m] 897 898 # [xx] Reset caches?? 899 900 # Start documenting 901 start_new_thread(document, args) 902 903 # Start the progress bar. 904 self._go_button['text'] = 'Stop' 905 self._afterid += 1 906 dt = 300 # How often to update, in milliseconds 907 self._update(dt, self._afterid)
      908
      909 - def _update_messages(self):
      910 while 1: 911 level, data = self._logger.read() 912 if data is None: break 913 self._messages['state'] = 'normal' 914 if level == 'header': 915 self._messages.insert('end', data, 'header') 916 elif level == 'uline': 917 self._messages.insert('end', data, 'uline header') 918 elif level >= log.ERROR: 919 data= data.rstrip()+'\n\n' 920 self._messages.insert('end', data, 'guierror') 921 elif level >= log.DOCSTRING_WARNING: 922 data= data.rstrip()+'\n\n' 923 self._messages.insert('end', data, 'warning') 924 elif log >= log.INFO: 925 data= data.rstrip()+'\n\n' 926 self._messages.insert('end', data, 'message') 927 # if data == '\n': 928 # if self._last_tag != 'header2': 929 # self._messages.insert('end', '\n', self._last_tag) 930 # elif data == '='*75: 931 # if self._messages.get('end-3c', 'end') == '\n\n\n': 932 # self._messages.delete('end-1c') 933 # self._in_header = 1 934 # self._messages.insert('end', ' '*75, 'uline header') 935 # self._last_tag = 'header' 936 # elif data == '-'*75: 937 # self._in_header = 0 938 # self._last_tag = 'header2' 939 # elif self._in_header: 940 # self._messages.insert('end', data, 'header') 941 # self._last_tag = 'header' 942 # elif re.match(r'\s*(L\d+:|-)?\s*Warning: ', data): 943 # self._messages.insert('end', data, 'warning') 944 # self._last_tag = 'warning' 945 # else: 946 # self._messages.insert('end', data, 'error') 947 # self._last_tag = 'error' 948 949 self._messages['state'] = 'disabled' 950 self._messages.yview('end')
      951
      952 - def _update(self, dt, id):
      953 if self._root is None: return 954 if self._progress[0] is None: return 955 if id != self._afterid: return 956 957 # Update the messages box 958 self._update_messages() 959 960 # Update the progress bar. 961 if self._progress[0] == 'done': p = self._W + DX 962 elif self._progress[0] == 'cancel': p = -5 963 else: p = DX + self._W * self._progress[0] 964 self._canvas.coords(self._r1, DX+1, DY+1, p, self._H+1) 965 self._canvas.coords(self._r2, DX, DY, p-1, self._H) 966 self._canvas.coords(self._r3, DX+1, DY+1, p, self._H+1) 967 968 # Are we done? 969 if self._progress[0] in ('done', 'cancel'): 970 if self._progress[0] == 'cancel': self._root.bell() 971 self._go_button['text'] = 'Start' 972 self._progress[0] = None 973 return 974 975 self._root.after(dt, self._update, dt, id)
      976
      977 - def _new(self, *e):
      978 self._module_list.delete(0, 'end') 979 self._name_entry.delete(0, 'end') 980 self._url_entry.delete(0, 'end') 981 self._docformat_var.set('epytext') 982 self._inheritance_var.set('grouped') 983 self._introspect_or_parse_var.set('both') 984 self._out_entry.delete(0, 'end') 985 self._module_entry.delete(0, 'end') 986 self._css_entry.delete(0, 'end') 987 self._help_entry.delete(0, 'end') 988 self._frames_var.set(1) 989 self._private_var.set(1) 990 self._imports_var.set(0) 991 self._css_var.set('default') 992 #self._private_css_var.set('default') 993 self._help_var.set('default') 994 self._filename = None 995 self._init_dir = None
      996
      997 - def _open(self, *e):
      998 title = 'Open project' 999 ftypes = [('Project file', '.prj'), 1000 ('All files', '*')] 1001 filename = askopenfilename(filetypes=ftypes, title=title, 1002 defaultextension='.css') 1003 if not filename: return 1004 self.open(filename)
      1005
      1006 - def open(self, prjfile):
      1007 from epydoc.docwriter.html_css import STYLESHEETS 1008 self._filename = prjfile 1009 try: 1010 opts = load(open(prjfile, 'r')) 1011 1012 modnames = list(opts.get('modules', [])) 1013 modnames.sort() 1014 self._module_list.delete(0, 'end') 1015 for name in modnames: 1016 self.add_module(name) 1017 self._module_entry.delete(0, 'end') 1018 1019 self._name_entry.delete(0, 'end') 1020 if opts.get('prj_name'): 1021 self._name_entry.insert(0, opts['prj_name']) 1022 1023 self._url_entry.delete(0, 'end') 1024 if opts.get('prj_url'): 1025 self._url_entry.insert(0, opts['prj_url']) 1026 1027 self._docformat_var.set(opts.get('docformat', 'epytext')) 1028 self._inheritance_var.set(opts.get('inheritance', 'grouped')) 1029 self._introspect_or_parse_var.set( 1030 opts.get('introspect_or_parse', 'both')) 1031 1032 self._help_entry.delete(0, 'end') 1033 if opts.get('help') is None: 1034 self._help_var.set('default') 1035 else: 1036 self._help_var.set('-other-') 1037 self._help_entry.insert(0, opts.get('help')) 1038 1039 self._out_entry.delete(0, 'end') 1040 self._out_entry.insert(0, opts.get('target', 'html')) 1041 1042 self._frames_var.set(opts.get('frames', 1)) 1043 self._private_var.set(opts.get('private', 1)) 1044 self._imports_var.set(opts.get('show_imports', 0)) 1045 1046 self._css_entry.delete(0, 'end') 1047 if opts.get('css', 'default') in STYLESHEETS.keys(): 1048 self._css_var.set(opts.get('css', 'default')) 1049 else: 1050 self._css_var.set('-other-') 1051 self._css_entry.insert(0, opts.get('css', 'default')) 1052 1053 #if opts.get('private_css', 'default') in STYLESHEETS.keys(): 1054 # self._private_css_var.set(opts.get('private_css', 'default')) 1055 #else: 1056 # self._private_css_var.set('-other-') 1057 # self._css_entry.insert(0, opts.get('private_css', 'default')) 1058 1059 except Exception, e: 1060 log.error('Error opening %s: %s' % (prjfile, e)) 1061 self._root.bell()
      1062
      1063 - def _save(self, *e):
      1064 if self._filename is None: return self._saveas() 1065 try: 1066 opts = self._getopts() 1067 dump(opts, open(self._filename, 'w')) 1068 except Exception, e: 1069 if self._filename is None: 1070 log.error('Error saving: %s' % e) 1071 else: 1072 log.error('Error saving %s: %s' % (self._filename, e)) 1073 self._root.bell()
      1074
      1075 - def _saveas(self, *e):
      1076 title = 'Save project as' 1077 ftypes = [('Project file', '.prj'), ('All files', '*')] 1078 filename = asksaveasfilename(filetypes=ftypes, title=title, 1079 defaultextension='.prj') 1080 if not filename: return 1081 self._filename = filename 1082 self._save()
  • 1083
    1084 -def _version():
    1085 """ 1086 Display the version information, and exit. 1087 @rtype: C{None} 1088 """ 1089 import epydoc 1090 print "Epydoc version %s" % epydoc.__version__ 1091 sys.exit(0)
    1092 1093 # At some point I could add: 1094 # --show-messages, --hide-messages 1095 # --show-options, --hide-options
    1096 -def _usage():
    1097 print 1098 print 'Usage: epydocgui [OPTIONS] [FILE.prj | MODULES...]' 1099 print 1100 print ' FILE.prj An epydoc GUI project file.' 1101 print ' MODULES... A list of Python modules to document.' 1102 print ' -V, --version Print the version of epydoc.' 1103 print ' -h, -?, --help, --usage Display this usage message' 1104 print ' --debug Do not suppress error messages' 1105 print 1106 sys.exit(0)
    1107
    1108 -def _error(s):
    1109 s = '%s; run "%s -h" for usage' % (s, os.path.basename(sys.argv[0])) 1110 if len(s) > 80: 1111 i = s.rfind(' ', 0, 80) 1112 if i>0: s = s[:i]+'\n'+s[i+1:] 1113 print >>sys.stderr, s 1114 sys.exit(1)
    1115
    1116 -def gui():
    1117 global DEBUG 1118 sys.stderr = sys.__stderr__ 1119 projects = [] 1120 modules = [] 1121 for arg in sys.argv[1:]: 1122 if arg[0] == '-': 1123 if arg != '-V': arg = arg.lower() 1124 if arg in ('-h', '--help', '-?', '--usage'): _usage() 1125 elif arg in ('-V', '--version'): _version() 1126 elif arg in ('--debug',): DEBUG = 1 1127 else: 1128 _error('Unknown parameter %r' % arg) 1129 elif arg[-4:] == '.prj': projects.append(arg) 1130 else: modules.append(arg) 1131 1132 if len(projects) > 1: 1133 _error('Too many projects') 1134 if len(projects) == 1: 1135 if len(modules) > 0: 1136 _error('You must specify either a project or a list of modules') 1137 if not os.path.exists(projects[0]): 1138 _error('Cannot open project file %s' % projects[0]) 1139 gui = EpydocGUI() 1140 gui.open(projects[0]) 1141 gui.mainloop() 1142 else: 1143 gui = EpydocGUI() 1144 for module in modules: gui.add_module(module, check=1) 1145 gui.mainloop()
    1146 1147 if __name__ == '__main__': gui() 1148
    epydoc-3.0.1+dfsg/doc/api/epydoc.docparser.ParseError-class.html0000644000175000017500000001445210750103050025030 0ustar pronovicpronovic epydoc.docparser.ParseError
    Package epydoc :: Module docparser :: Class ParseError
    [hide private]
    [frames] | no frames]

    Class ParseError

    source code


    An exception that is used to signify that docparser encountered syntactically invalid Python code while processing a Python source file.

    Instance Methods [hide private]

    Inherited from exceptions.Exception: __getitem__, __init__, __str__

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr._Linebreak-class.html0000644000175000017500000001470510750103050026477 0ustar pronovicpronovic epydoc.markup.pyval_repr._Linebreak
    Package epydoc :: Package markup :: Module pyval_repr :: Class _Linebreak
    [hide private]
    [frames] | no frames]

    Class _Linebreak

    source code


    A control-flow exception that is raised when PyvalColorizer generates a string containing a newline, but the state object's linebreakok variable is False.

    Instance Methods [hide private]

    Inherited from exceptions.Exception: __getitem__, __init__, __str__

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink-module.html0000644000175000017500000006070510750103050024273 0ustar pronovicpronovic epydoc.docwriter.xlink
    Package epydoc :: Package docwriter :: Module xlink
    [hide private]
    [frames] | no frames]

    Module xlink

    source code

    A Docutils interpreted text role for cross-API reference support.

    This module allows a Docutils document to refer to elements defined in external API documentation. It is possible to refer to many external API from the same document.

    Each API documentation is assigned a new interpreted text role: using such interpreted text, an user can specify an object name inside an API documentation. The system will convert such text into an url and generate a reference to it. For example, if the API db is defined, being a database package, then a certain method may be referred as:

    :db:`Connection.cursor()`
    

    To define a new API, an index file must be provided. This file contains a mapping from the object name to the URL part required to resolve such object.

    Index file

    Each line in the the index file describes an object.

    Each line contains the fully qualified name of the object and the URL at which the documentation is located. The fields are separated by a <tab> character.

    The URL's in the file are relative from the documentation root: the system can be configured to add a prefix in front of each returned URL.

    Allowed names

    When a name is used in an API text role, it is split over any separator. The separators defined are '.', '::', '->'. All the text from the first noise char (neither a separator nor alphanumeric or '_') is discarded. The same algorithm is applied when the index file is read.

    First the sequence of name parts is looked for in the provided index file. If no matching name is found, a partial match against the trailing part of the names in the index is performed. If no object is found, or if the trailing part of the name may refer to many objects, a warning is issued and no reference is created.

    Configuration

    This module provides the class ApiLinkReader a replacement for the Docutils standalone reader. Such reader specifies the settings required for the API canonical roles configuration. The same command line options are exposed by Epydoc.

    The script apirst2html.py is a frontend for the ApiLinkReader reader.

    API Linking Options:

    --external-api=NAME
                        Define a new API document.  A new interpreted text
                        role NAME will be added.
    --external-api-file=NAME:FILENAME
                        Use records in FILENAME to resolve objects in the API
                        named NAME.
    --external-api-root=NAME:STRING
                        Use STRING as prefix for the URL generated from the
                        API NAME.
    

    Version: 1586

    Author: Daniele Varrazzo

    Copyright: Copyright (C) 2007 by Daniele Varrazzo

    Classes [hide private]
      UrlGenerator
    Generate URL from an object name.
      VoidUrlGenerator
    Don't actually know any url, but don't report any error.
      DocUrlGenerator
    Read a documentation index and generate URL's for it.
        Command line parsing
      ApiLinkReader
    A Docutils standalone reader allowing external documentation links.
    Functions [hide private]
        API register
     
    register_api(name, generator=None)
    Register the API name into the api_register.
    source code
     
    set_api_file(name, file)
    Set an URL generator populated with data from file.
    source code
     
    set_api_root(name, prefix)
    Set the root for the URLs returned by a registered URL generator.
    source code
     
    create_api_role(name, problematic)
    Create and register a new role to create links for an API documentation.
    source code
        Command line parsing
     
    split_name(value)
    Split an option in form NAME:VALUE and check if NAME exists.
    source code
    Variables [hide private]
        API register
      api_register = {}
    Mapping from the API name to the UrlGenerator to be used.
    Function Details [hide private]

    register_api(name, generator=None)

    source code 

    Register the API name into the api_register.

    A registered API will be available to the markup as the interpreted text role name.

    If a generator is not provided, register a VoidUrlGenerator instance: in this case no warning will be issued for missing names, but no URL will be generated and all the dotted names will simply be rendered as literals.

    Parameters:
    • name (str) - the name of the generator to be registered
    • generator (UrlGenerator) - the object to register to translate names into URLs.

    set_api_file(name, file)

    source code 

    Set an URL generator populated with data from file.

    Use file to populate a new DocUrlGenerator instance and register it as name.

    Parameters:
    • name (str) - the name of the generator to be registered
    • file (str or file) - the file to parse populate the URL generator

    set_api_root(name, prefix)

    source code 
    Set the root for the URLs returned by a registered URL generator.
    Parameters:
    • name (str) - the name of the generator to be updated
    • prefix (str) - the prefix for the generated URL's
    Raises:
    • IndexError - name is not a registered generator

    create_api_role(name, problematic)

    source code 

    Create and register a new role to create links for an API documentation.

    Create a role called name, which will use the URL resolver registered as name in api_register to create a link for an object.

    Parameters:
    • name (str) - name of the role to create.
    • problematic (bool) - if True, the registered role will create problematic nodes in case of failed references. If False, a warning will be raised anyway, but the output will appear as an ordinary literal.

    Variables Details [hide private]

    api_register

    Mapping from the API name to the UrlGenerator to be used.

    Use register_api() to add new generators to the register.

    Value:
    {}
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docparser-pysrc.html0000644000175000017500000245267010750103050023012 0ustar pronovicpronovic epydoc.docparser
    Package epydoc :: Module docparser
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docparser

       1  # epydoc -- Source code parsing 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: docparser.py 1673 2008-01-29 05:42:58Z edloper $ 
       8   
       9  """ 
      10  Extract API documentation about python objects by parsing their source 
      11  code. 
      12   
      13  The function L{parse_docs()}, which provides the main interface 
      14  of this module, reads and parses the Python source code for a 
      15  module, and uses it to create an L{APIDoc} object containing 
      16  the API documentation for the variables and values defined in 
      17  that modules. 
      18   
      19  Currently, C{parse_docs()} extracts documentation from the following 
      20  source code constructions: 
      21   
      22    - module docstring 
      23    - import statements 
      24    - class definition blocks 
      25    - function definition blocks 
      26    - assignment statements 
      27      - simple assignment statements 
      28      - assignment statements with multiple C{'='}s 
      29      - assignment statements with unpacked left-hand sides 
      30      - assignment statements that wrap a function in classmethod 
      31        or staticmethod. 
      32      - assignment to special variables __path__, __all__, and 
      33        __docformat__. 
      34    - delete statements 
      35   
      36  C{parse_docs()} does not yet support the following source code 
      37  constructions: 
      38   
      39    - assignment statements that create properties 
      40   
      41  By default, C{parse_docs()} will expore the contents of top-level 
      42  C{try} and C{if} blocks.  If desired, C{parse_docs()} can also 
      43  be configured to explore the contents of C{while} and C{for} blocks. 
      44  (See the configuration constants, below.) 
      45   
      46  @todo: Make it possible to extend the functionality of C{parse_docs()}, 
      47         by replacing process_line with a dispatch table that can be 
      48         customized (similarly to C{docintrospector.register_introspector()}). 
      49  """ 
      50  __docformat__ = 'epytext en' 
      51   
      52  ###################################################################### 
      53  ## Imports 
      54  ###################################################################### 
      55   
      56  # Python source code parsing: 
      57  import token, tokenize 
      58  # Finding modules: 
      59  import imp 
      60  # File services: 
      61  import os, os.path, sys 
      62  # Unicode: 
      63  import codecs 
      64  # API documentation encoding: 
      65  from epydoc.apidoc import * 
      66  # For looking up the docs of builtins: 
      67  import __builtin__, exceptions 
      68  import epydoc.docintrospecter  
      69  # Misc utility functions: 
      70  from epydoc.util import * 
      71  # Backwards compatibility 
      72  from epydoc.compat import * 
      73   
      74  ###################################################################### 
      75  ## Doc Parser 
      76  ###################################################################### 
      77   
    
    78 -class ParseError(Exception):
    79 """ 80 An exception that is used to signify that C{docparser} encountered 81 syntactically invalid Python code while processing a Python source 82 file. 83 """
    84 85 _moduledoc_cache = {} 86 """A cache of C{ModuleDoc}s that we've already created. 87 C{_moduledoc_cache} is a dictionary mapping from filenames to 88 C{ValueDoc} objects. 89 @type: C{dict}""" 90 91 #//////////////////////////////////////////////////////////// 92 # Configuration Constants 93 #//////////////////////////////////////////////////////////// 94 95 #{ Configuration Constants: Control Flow 96 PARSE_TRY_BLOCKS = True 97 """Should the contents of C{try} blocks be examined?""" 98 PARSE_EXCEPT_BLOCKS = True 99 """Should the contents of C{except} blocks be examined?""" 100 PARSE_FINALLY_BLOCKS = True 101 """Should the contents of C{finally} blocks be examined?""" 102 PARSE_IF_BLOCKS = True 103 """Should the contents of C{if} blocks be examined?""" 104 PARSE_ELSE_BLOCKS = True 105 """Should the contents of C{else} and C{elif} blocks be examined?""" 106 PARSE_WHILE_BLOCKS = False 107 """Should the contents of C{while} blocks be examined?""" 108 PARSE_FOR_BLOCKS = False 109 """Should the contents of C{for} blocks be examined?""" 110 111 #{ Configuration Constants: Imports 112 IMPORT_HANDLING = 'link' 113 """What should C{docparser} do when it encounters an import 114 statement? 115 - C{'link'}: Create variabledoc objects with imported_from pointers 116 to the source object. 117 - C{'parse'}: Parse the imported file, to find the actual 118 documentation for the imported object. (This will fall back 119 to the 'link' behavior if the imported file can't be parsed, 120 e.g., if it's a builtin.) 121 """ 122 123 IMPORT_STAR_HANDLING = 'parse' 124 """When C{docparser} encounters a C{'from M{m} import *'} 125 statement, and is unable to parse C{M{m}} (either because 126 L{IMPORT_HANDLING}=C{'link'}, or because parsing failed), how 127 should it determine the list of identifiers expored by C{M{m}}? 128 - C{'ignore'}: ignore the import statement, and don't create 129 any new variables. 130 - C{'parse'}: parse it to find a list of the identifiers that it 131 exports. (This will fall back to the 'ignore' behavior if the 132 imported file can't be parsed, e.g., if it's a builtin.) 133 - C{'introspect'}: import the module and introspect it (using C{dir}) 134 to find a list of the identifiers that it exports. (This will 135 fall back to the 'ignore' behavior if the imported file can't 136 be parsed, e.g., if it's a builtin.) 137 """ 138 139 DEFAULT_DECORATOR_BEHAVIOR = 'transparent' 140 """When C{DocParse} encounters an unknown decorator, what should 141 it do to the documentation of the decorated function? 142 - C{'transparent'}: leave the function's documentation as-is. 143 - C{'opaque'}: replace the function's documentation with an 144 empty C{ValueDoc} object, reflecting the fact that we have no 145 knowledge about what value the decorator returns. 146 """ 147 148 BASE_HANDLING = 'parse'#'link' 149 """What should C{docparser} do when it encounters a base class that 150 was imported from another module? 151 - C{'link'}: Create a valuedoc with a C{proxy_for} pointer to the 152 base class. 153 - C{'parse'}: Parse the file containing the base class, to find 154 the actual documentation for it. (This will fall back to the 155 'link' behavior if the imported file can't be parsed, e.g., if 156 it's a builtin.) 157 """ 158 159 #{ Configuration Constants: Comment docstrings 160 COMMENT_DOCSTRING_MARKER = '#:' 161 """The prefix used to mark comments that contain attribute 162 docstrings for variables.""" 163 164 #{ Configuration Constants: Grouping 165 START_GROUP_MARKER = '#{' 166 """The prefix used to mark a comment that starts a group. This marker 167 should be followed (on the same line) by the name of the group. 168 Following a start-group comment, all variables defined at the same 169 indentation level will be assigned to this group name, until the 170 parser reaches the end of the file, a matching end-group comment, or 171 another start-group comment at the same indentation level. 172 """ 173 174 END_GROUP_MARKER = '#}' 175 """The prefix used to mark a comment that ends a group. See 176 L{START_GROUP_MARKER}.""" 177 178 #///////////////////////////////////////////////////////////////// 179 #{ Module parser 180 #///////////////////////////////////////////////////////////////// 181
    182 -def parse_docs(filename=None, name=None, context=None, is_script=False):
    183 """ 184 Generate the API documentation for a specified object by 185 parsing Python source files, and return it as a L{ValueDoc}. 186 The object to generate documentation for may be specified 187 using the C{filename} parameter I{or} the C{name} parameter. 188 (It is an error to specify both a filename and a name; or to 189 specify neither a filename nor a name). 190 191 @param filename: The name of the file that contains the python 192 source code for a package, module, or script. If 193 C{filename} is specified, then C{parse} will return a 194 C{ModuleDoc} describing its contents. 195 @param name: The fully-qualified python dotted name of any 196 value (including packages, modules, classes, and 197 functions). C{parse_docs()} will automatically figure out 198 which module(s) it needs to parse in order to find the 199 documentation for the specified object. 200 @param context: The API documentation for the package that 201 contains C{filename}. If no context is given, then 202 C{filename} is assumed to contain a top-level module or 203 package. It is an error to specify a C{context} if the 204 C{name} argument is used. 205 @rtype: L{ValueDoc} 206 """ 207 # Always introspect __builtins__ & exceptions (e.g., in case 208 # they're used as base classes.) 209 epydoc.docintrospecter.introspect_docs(__builtin__) 210 epydoc.docintrospecter.introspect_docs(exceptions) 211 212 # If our input is a python object name, then delegate to 213 # _find(). 214 if filename is None and name is not None: 215 if context: 216 raise ValueError("context should only be specified together " 217 "with filename, not with name.") 218 name = DottedName(name) 219 val_doc = _find(name) 220 if val_doc.canonical_name is UNKNOWN: 221 val_doc.canonical_name = name 222 return val_doc 223 224 # If our input is a filename, then create a ModuleDoc for it, 225 # and use process_file() to populate its attributes. 226 elif filename is not None and name is None: 227 # Use a python source version, if possible. 228 if not is_script: 229 try: filename = py_src_filename(filename) 230 except ValueError, e: raise ImportError('%s' % e) 231 232 # Check the cache, first. 233 if filename in _moduledoc_cache: 234 return _moduledoc_cache[filename] 235 236 log.info("Parsing %s" % filename) 237 238 # If the context wasn't provided, then check if the file is in 239 # a package directory. If so, then update basedir & name to 240 # contain the topmost package's directory and the fully 241 # qualified name for this file. (This update assume the 242 # default value of __path__ for the parent packages; if the 243 # parent packages override their __path__s, then this can 244 # cause us not to find the value.) 245 if context is None and not is_script: 246 basedir = os.path.split(filename)[0] 247 name = os.path.splitext(os.path.split(filename)[1])[0] 248 if name == '__init__': 249 basedir, name = os.path.split(basedir) 250 context = _parse_package(basedir) 251 252 # Figure out the canonical name of the module we're parsing. 253 if not is_script: 254 module_name, is_pkg = _get_module_name(filename, context) 255 else: 256 module_name = DottedName(munge_script_name(filename)) 257 is_pkg = False 258 259 # Create a new ModuleDoc for the module, & add it to the cache. 260 module_doc = ModuleDoc(canonical_name=module_name, variables={}, 261 sort_spec=[], imports=[], 262 filename=filename, package=context, 263 is_package=is_pkg, submodules=[], 264 docs_extracted_by='parser') 265 module_doc.defining_module = module_doc 266 _moduledoc_cache[filename] = module_doc 267 268 # Set the module's __path__ to its default value. 269 if is_pkg: 270 module_doc.path = [os.path.split(module_doc.filename)[0]] 271 272 # Add this module to the parent package's list of submodules. 273 if context is not None: 274 context.submodules.append(module_doc) 275 276 # Tokenize & process the contents of the module's source file. 277 try: 278 process_file(module_doc) 279 except tokenize.TokenError, e: 280 msg, (srow, scol) = e.args 281 raise ParseError('Error during parsing: %s ' 282 '(%s, line %d, char %d)' % 283 (msg, module_doc.filename, srow, scol)) 284 except IndentationError, e: 285 raise ParseError('Error during parsing: %s (%s)' % 286 (e, module_doc.filename)) 287 288 # Handle any special variables (__path__, __docformat__, etc.) 289 handle_special_module_vars(module_doc) 290 291 # Return the completed ModuleDoc 292 return module_doc 293 else: 294 raise ValueError("Expected exactly one of the following " 295 "arguments: name, filename")
    296
    297 -def _parse_package(package_dir):
    298 """ 299 If the given directory is a package directory, then parse its 300 __init__.py file (and the __init__.py files of all ancestor 301 packages); and return its C{ModuleDoc}. 302 """ 303 if not is_package_dir(package_dir): 304 return None 305 parent_dir = os.path.split(package_dir)[0] 306 parent_doc = _parse_package(parent_dir) 307 package_file = os.path.join(package_dir, '__init__') 308 return parse_docs(filename=package_file, context=parent_doc)
    309 310 # Special vars: 311 # C{__docformat__}, C{__all__}, and C{__path__}.
    312 -def handle_special_module_vars(module_doc):
    313 # If __docformat__ is defined, parse its value. 314 toktree = _module_var_toktree(module_doc, '__docformat__') 315 if toktree is not None: 316 try: module_doc.docformat = parse_string(toktree) 317 except: pass 318 del module_doc.variables['__docformat__'] 319 320 # If __all__ is defined, parse its value. 321 toktree = _module_var_toktree(module_doc, '__all__') 322 if toktree is not None: 323 try: 324 public_names = set(parse_string_list(toktree)) 325 for name, var_doc in module_doc.variables.items(): 326 if name in public_names: 327 var_doc.is_public = True 328 if not isinstance(var_doc, ModuleDoc): 329 var_doc.is_imported = False 330 else: 331 var_doc.is_public = False 332 except ParseError: 333 # If we couldn't parse the list, give precedence to introspection. 334 for name, var_doc in module_doc.variables.items(): 335 if not isinstance(var_doc, ModuleDoc): 336 var_doc.is_imported = UNKNOWN 337 del module_doc.variables['__all__'] 338 339 # If __path__ is defined, then extract its value (pkgs only) 340 if module_doc.is_package: 341 toktree = _module_var_toktree(module_doc, '__path__') 342 if toktree is not None: 343 try: 344 module_doc.path = parse_string_list(toktree) 345 except ParseError: 346 pass # [xx] 347 del module_doc.variables['__path__']
    348
    349 -def _module_var_toktree(module_doc, name):
    350 var_doc = module_doc.variables.get(name) 351 if (var_doc is None or var_doc.value in (None, UNKNOWN) or 352 var_doc.value.toktree is UNKNOWN): 353 return None 354 else: 355 return var_doc.value.toktree
    356 357 #//////////////////////////////////////////////////////////// 358 #{ Module Lookup 359 #//////////////////////////////////////////////////////////// 360
    361 -def _find(name, package_doc=None):
    362 """ 363 Return the API documentaiton for the object whose name is 364 C{name}. C{package_doc}, if specified, is the API 365 documentation for the package containing the named object. 366 """ 367 # If we're inside a package, then find the package's path. 368 if package_doc is None: 369 path = None 370 elif package_doc.path is not UNKNOWN: 371 path = package_doc.path 372 else: 373 path = [os.path.split(package_doc.filename)[0]] 374 375 # The leftmost identifier in `name` should be a module or 376 # package on the given path; find it and parse it. 377 filename = _get_filename(name[0], path) 378 module_doc = parse_docs(filename, context=package_doc) 379 380 # If the name just has one identifier, then the module we just 381 # parsed is the object we're looking for; return it. 382 if len(name) == 1: return module_doc 383 384 # Otherwise, we're looking for something inside the module. 385 # First, check to see if it's in a variable (but ignore 386 # variables that just contain imported submodules). 387 if not _is_submodule_import_var(module_doc, name[1]): 388 try: return _find_in_namespace(name[1:], module_doc) 389 except ImportError: pass 390 391 # If not, then check to see if it's in a subpackage. 392 if module_doc.is_package: 393 return _find(name[1:], module_doc) 394 395 # If it's not in a variable or a subpackage, then we can't 396 # find it. 397 raise ImportError('Could not find value')
    398
    399 -def _is_submodule_import_var(module_doc, var_name):
    400 """ 401 Return true if C{var_name} is the name of a variable in 402 C{module_doc} that just contains an C{imported_from} link to a 403 submodule of the same name. (I.e., is a variable created when 404 a package imports one of its own submodules.) 405 """ 406 var_doc = module_doc.variables.get(var_name) 407 full_var_name = DottedName(module_doc.canonical_name, var_name) 408 return (var_doc is not None and 409 var_doc.imported_from == full_var_name)
    410
    411 -def _find_in_namespace(name, namespace_doc):
    412 if name[0] not in namespace_doc.variables: 413 raise ImportError('Could not find value') 414 415 # Look up the variable in the namespace. 416 var_doc = namespace_doc.variables[name[0]] 417 if var_doc.value is UNKNOWN: 418 raise ImportError('Could not find value') 419 val_doc = var_doc.value 420 421 # If the variable's value was imported, then follow its 422 # alias link. 423 if var_doc.imported_from not in (None, UNKNOWN): 424 return _find(var_doc.imported_from+name[1:]) 425 426 # Otherwise, if the name has one identifier, then this is the 427 # value we're looking for; return it. 428 elif len(name) == 1: 429 return val_doc 430 431 # Otherwise, if this value is a namespace, look inside it. 432 elif isinstance(val_doc, NamespaceDoc): 433 return _find_in_namespace(name[1:], val_doc) 434 435 # Otherwise, we ran into a dead end. 436 else: 437 raise ImportError('Could not find value')
    438
    439 -def _get_filename(identifier, path=None):
    440 if path is UNKNOWN: path = None 441 try: 442 fp, filename, (s,m,typ) = imp.find_module(identifier, path) 443 if fp is not None: fp.close() 444 except ImportError: 445 raise ImportError, 'No Python source file found.' 446 447 if typ == imp.PY_SOURCE: 448 return filename 449 elif typ == imp.PY_COMPILED: 450 # See if we can find a corresponding non-compiled version. 451 filename = re.sub('.py\w$', '.py', filename) 452 if not os.path.exists(filename): 453 raise ImportError, 'No Python source file found.' 454 return filename 455 elif typ == imp.PKG_DIRECTORY: 456 filename = os.path.join(filename, '__init__.py') 457 if not os.path.exists(filename): 458 filename = os.path.join(filename, '__init__.pyw') 459 if not os.path.exists(filename): 460 raise ImportError, 'No package file found.' 461 return filename 462 elif typ == imp.C_BUILTIN: 463 raise ImportError, 'No Python source file for builtin modules.' 464 elif typ == imp.C_EXTENSION: 465 raise ImportError, 'No Python source file for c extensions.' 466 else: 467 raise ImportError, 'No Python source file found.'
    468 469 #///////////////////////////////////////////////////////////////// 470 #{ File tokenization loop 471 #///////////////////////////////////////////////////////////////// 472
    473 -def process_file(module_doc):
    474 """ 475 Read the given C{ModuleDoc}'s file, and add variables 476 corresponding to any objects defined in that file. In 477 particular, read and tokenize C{module_doc.filename}, and 478 process each logical line using L{process_line()}. 479 """ 480 # Keep track of the current line number: 481 lineno = None 482 483 # Use this list to collect the tokens on a single logical line: 484 line_toks = [] 485 486 # This list contains one APIDoc for each indentation level. 487 # The first element is the APIDoc for the module, and each 488 # subsequent element is the APIDoc for the object at that 489 # indentation level. The final element of the list is the 490 # C{APIDoc} for the entity that we're currently processing. 491 parent_docs = [module_doc] 492 493 # The APIDoc for the object that was defined by the previous 494 # line, if any; or None otherwise. This is used to update 495 # parent_docs when we encounter an indent; and to decide what 496 # object (if any) is described by a docstring. 497 prev_line_doc = module_doc 498 499 # A list of comments that occur before or on the current 500 # logical line, used to build the comment docstring. Each 501 # element is a tuple (comment_text, comment_lineno). 502 comments = [] 503 504 # A list of decorator lines that occur before the current 505 # logical line. This is used so we can process a function 506 # declaration line and its decorators all at once. 507 decorators = [] 508 509 # A list of group names, one for each indentation level. This is 510 # used to keep track groups that are defined by comment markers 511 # START_GROUP_MARKER and END_GROUP_MARKER. 512 groups = [None] 513 514 # When we encounter a comment start group marker, set this to the 515 # name of the group; but wait until we're ready to process the 516 # next line before we actually set groups[-1] to this value. This 517 # is necessary because at the top of a block, the tokenizer gives 518 # us comments before the INDENT token; but if we encounter a group 519 # start marker at the top of a block, then we want it to apply 520 # inside that block, not outside it. 521 start_group = None 522 523 # Check if the source file declares an encoding. 524 encoding = get_module_encoding(module_doc.filename) 525 526 # The token-eating loop: 527 try: 528 module_file = codecs.open(module_doc.filename, 'rU', encoding) 529 except LookupError: 530 log.warning("Unknown encoding %r for %s; using the default" 531 "encoding instead (iso-8859-1)" % 532 (encoding, module_doc.filename)) 533 encoding = 'iso-8859-1' 534 module_file = codecs.open(module_doc.filename, 'rU', encoding) 535 tok_iter = tokenize.generate_tokens(module_file.readline) 536 for toktype, toktext, (srow,scol), (erow,ecol), line_str in tok_iter: 537 # BOM encoding marker: ignore. 538 if (toktype == token.ERRORTOKEN and 539 (toktext == u'\ufeff' or 540 toktext.encode(encoding) == '\xef\xbb\xbf')): 541 pass 542 543 # Error token: abort 544 elif toktype == token.ERRORTOKEN: 545 raise ParseError('Error during parsing: invalid syntax ' 546 '(%s, line %d, char %d: %r)' % 547 (module_doc.filename, srow, scol, toktext)) 548 549 # Indent token: update the parent_doc stack. 550 elif toktype == token.INDENT: 551 if prev_line_doc is None: 552 parent_docs.append(parent_docs[-1]) 553 else: 554 parent_docs.append(prev_line_doc) 555 groups.append(None) 556 557 # Dedent token: update the parent_doc stack. 558 elif toktype == token.DEDENT: 559 if line_toks == []: 560 parent_docs.pop() 561 groups.pop() 562 else: 563 # This *should* only happen if the file ends on an 564 # indented line, with no final newline. 565 # (otherwise, this is the wrong thing to do.) 566 pass 567 568 # Line-internal newline token: if we're still at the start of 569 # the logical line, and we've seen one or more comment lines, 570 # then discard them: blank lines are not allowed between a 571 # comment block and the thing it describes. 572 elif toktype == tokenize.NL: 573 if comments and not line_toks: 574 log.warning('Ignoring docstring comment block followed by ' 575 'a blank line in %r on line %r' % 576 (module_doc.filename, srow-1)) 577 comments = [] 578 579 # Comment token: add to comments if appropriate. 580 elif toktype == tokenize.COMMENT: 581 if toktext.startswith(COMMENT_DOCSTRING_MARKER): 582 comment_line = toktext[len(COMMENT_DOCSTRING_MARKER):].rstrip() 583 if comment_line.startswith(" "): 584 comment_line = comment_line[1:] 585 comments.append( [comment_line, srow]) 586 elif toktext.startswith(START_GROUP_MARKER): 587 start_group = toktext[len(START_GROUP_MARKER):].strip() 588 elif toktext.startswith(END_GROUP_MARKER): 589 for i in range(len(groups)-1, -1, -1): 590 if groups[i]: 591 groups[i] = None 592 break 593 else: 594 log.warning("Got group end marker without a corresponding " 595 "start marker in %r on line %r" % 596 (module_doc.filename, srow)) 597 598 # Normal token: Add it to line_toks. (If it's a non-unicode 599 # string literal, then we need to re-encode using the file's 600 # encoding, to get back to the original 8-bit data; and then 601 # convert that string with 8-bit data to a 7-bit ascii 602 # representation.) 603 elif toktype != token.NEWLINE and toktype != token.ENDMARKER: 604 if lineno is None: lineno = srow 605 if toktype == token.STRING: 606 str_prefixes = re.match('[^\'"]*', toktext).group() 607 if 'u' not in str_prefixes: 608 s = toktext.encode(encoding) 609 toktext = decode_with_backslashreplace(s) 610 line_toks.append( (toktype, toktext) ) 611 612 # Decorator line: add it to the decorators list. 613 elif line_toks and line_toks[0] == (token.OP, '@'): 614 decorators.append(shallow_parse(line_toks)) 615 line_toks = [] 616 617 # End of line token, but nothing to do. 618 elif line_toks == []: 619 pass 620 621 # End of line token: parse the logical line & process it. 622 else: 623 if start_group: 624 groups[-1] = start_group 625 start_group = None 626 627 if parent_docs[-1] != 'skip_block': 628 try: 629 prev_line_doc = process_line( 630 shallow_parse(line_toks), parent_docs, prev_line_doc, 631 lineno, comments, decorators, encoding) 632 except ParseError, e: 633 raise ParseError('Error during parsing: invalid ' 634 'syntax (%s, line %d) -- %s' % 635 (module_doc.filename, lineno, e)) 636 except KeyboardInterrupt, e: raise 637 except Exception, e: 638 log.error('Internal error during parsing (%s, line ' 639 '%s):\n%s' % (module_doc.filename, lineno, e)) 640 raise 641 642 # grouping... 643 if groups[-1] and prev_line_doc not in (None, 'skip_block'): 644 if isinstance(prev_line_doc, VariableDoc): 645 # prev_line_doc's container will only be 646 # UNKNOWN if it's an instance variable that 647 # didn't have a doc-comment, but might still 648 # be followed by a docstring. Since we 649 # tokenize in order, we can't do lookahead to 650 # see if the variable will have a comment; but 651 # it should only be added to the container if 652 # it does. So we defer the grouping of that 653 # to be handled by process_docstring instead. 654 if prev_line_doc.container is not UNKNOWN: 655 add_to_group(prev_line_doc.container, 656 prev_line_doc, groups[-1]) 657 elif isinstance(parent_docs[-1], NamespaceDoc): 658 add_to_group(parent_docs[-1], prev_line_doc, 659 groups[-1]) 660 else: 661 prev_line_doc = None 662 663 # Reset line contents. 664 line_toks = [] 665 lineno = None 666 comments = [] 667 decorators = []
    668
    669 -def add_to_group(container, api_doc, group_name):
    670 if container.group_specs is UNKNOWN: 671 container.group_specs = [] 672 673 if isinstance(api_doc, VariableDoc): 674 var_name = api_doc.name 675 else: 676 if api_doc.canonical_name is UNKNOWN: log.debug('ouch', `api_doc`) 677 var_name = api_doc.canonical_name[-1] 678 679 for (name, group_vars) in container.group_specs: 680 if name == group_name: 681 group_vars.append(var_name) 682 return 683 else: 684 container.group_specs.append( (group_name, [var_name]) )
    685
    686 -def script_guard(line):
    687 """Detect the idiomatic trick C{if __name__ == "__main__":}""" 688 return (len(line) == 5 689 and line[1][1] == '__name__' # this is the most selective 690 and line[0][1] == 'if' 691 and line[2][1] == '==' 692 and line[4][1] == ':' 693 and line[3][1][1:-1] == '__main__')
    694 695 #///////////////////////////////////////////////////////////////// 696 #{ Shallow parser 697 #///////////////////////////////////////////////////////////////// 698
    699 -def shallow_parse(line_toks):
    700 """ 701 Given a flat list of tokens, return a nested tree structure 702 (called a X{token tree}), whose leaves are identical to the 703 original list, but whose structure reflects the structure 704 implied by the grouping tokens (i.e., parenthases, braces, and 705 brackets). If the parenthases, braces, and brackets do not 706 match, or are not balanced, then raise a ParseError. 707 708 Assign some structure to a sequence of structure (group parens). 709 """ 710 stack = [[]] 711 parens = [] 712 for tok in line_toks: 713 toktype, toktext = tok 714 if toktext in ('(','[','{'): 715 parens.append(tok) 716 stack.append([tok]) 717 elif toktext in ('}',']',')'): 718 if not parens: 719 raise ParseError('Unbalanced parens') 720 left_paren = parens.pop()[1] 721 if left_paren+toktext not in ('()', '[]', '{}'): 722 raise ParseError('Mismatched parens') 723 lst = stack.pop() 724 lst.append(tok) 725 stack[-1].append(lst) 726 else: 727 stack[-1].append(tok) 728 if len(stack) != 1 or len(parens) != 0: 729 raise ParseError('Unbalanced parens') 730 return stack[0]
    731 732 #///////////////////////////////////////////////////////////////// 733 #{ Line processing 734 #///////////////////////////////////////////////////////////////// 735 # The methods process_*() are used to handle lines. 736
    737 -def process_line(line, parent_docs, prev_line_doc, lineno, 738 comments, decorators, encoding):
    739 """ 740 @return: C{new-doc}, C{decorator}..? 741 """ 742 args = (line, parent_docs, prev_line_doc, lineno, 743 comments, decorators, encoding) 744 745 if not line: # blank line. 746 return None 747 elif (token.OP, ':') in line[:-1]: 748 return process_one_line_block(*args) 749 elif (token.OP, ';') in line: 750 return process_multi_stmt(*args) 751 elif line[0] == (token.NAME, 'def'): 752 return process_funcdef(*args) 753 elif line[0] == (token.OP, '@'): 754 return process_funcdef(*args) 755 elif line[0] == (token.NAME, 'class'): 756 return process_classdef(*args) 757 elif line[0] == (token.NAME, 'import'): 758 return process_import(*args) 759 elif line[0] == (token.NAME, 'from'): 760 return process_from_import(*args) 761 elif line[0] == (token.NAME, 'del'): 762 return process_del(*args) 763 elif len(line)==1 and line[0][0] == token.STRING: 764 return process_docstring(*args) 765 elif (token.OP, '=') in line: 766 return process_assignment(*args) 767 elif (line[0][0] == token.NAME and 768 line[0][1] in CONTROL_FLOW_KEYWORDS): 769 return process_control_flow_line(*args) 770 else: 771 return None
    772 # [xx] do something with control structures like for/if? 773 774 #///////////////////////////////////////////////////////////////// 775 # Line handler: control flow 776 #///////////////////////////////////////////////////////////////// 777 778 CONTROL_FLOW_KEYWORDS = [ 779 #: A list of the control flow keywords. If a line begins with 780 #: one of these keywords, then it should be handled by 781 #: C{process_control_flow_line}. 782 'if', 'elif', 'else', 'while', 'for', 'try', 'except', 'finally'] 783
    784 -def process_control_flow_line(line, parent_docs, prev_line_doc, 785 lineno, comments, decorators, encoding):
    786 keyword = line[0][1] 787 788 # If it's a 'for' block: create the loop variable. 789 if keyword == 'for' and PARSE_FOR_BLOCKS: 790 loopvar_name = parse_dotted_name( 791 split_on(line[1:], (token.NAME, 'in'))[0]) 792 parent = get_lhs_parent(loopvar_name, parent_docs) 793 if parent is not None: 794 var_doc = VariableDoc(name=loopvar_name[-1], is_alias=False, 795 is_imported=False, is_instvar=False, 796 docs_extracted_by='parser') 797 set_variable(parent, var_doc) 798 799 if ((keyword == 'if' and PARSE_IF_BLOCKS and not script_guard(line)) or 800 (keyword == 'elif' and PARSE_ELSE_BLOCKS) or 801 (keyword == 'else' and PARSE_ELSE_BLOCKS) or 802 (keyword == 'while' and PARSE_WHILE_BLOCKS) or 803 (keyword == 'for' and PARSE_FOR_BLOCKS) or 804 (keyword == 'try' and PARSE_TRY_BLOCKS) or 805 (keyword == 'except' and PARSE_EXCEPT_BLOCKS) or 806 (keyword == 'finally' and PARSE_FINALLY_BLOCKS)): 807 # Return "None" to indicate that we should process the 808 # block using the same context that we were already in. 809 return None 810 else: 811 # Return 'skip_block' to indicate that we should ignore 812 # the contents of this block. 813 return 'skip_block'
    814 815 #///////////////////////////////////////////////////////////////// 816 # Line handler: imports 817 #///////////////////////////////////////////////////////////////// 818 # [xx] I could optionally add ValueDoc's for the imported 819 # variables with proxy_for set to the imported source; but 820 # I don't think I gain much of anything by doing so. 821
    822 -def process_import(line, parent_docs, prev_line_doc, lineno, 823 comments, decorators, encoding):
    824 if not isinstance(parent_docs[-1], NamespaceDoc): return 825 826 names = split_on(line[1:], (token.OP, ',')) 827 828 for name in names: 829 name_pieces = split_on(name, (token.NAME, 'as')) 830 if len(name_pieces) == 1: 831 src_name = parse_dotted_name(name_pieces[0]) 832 _import_var(src_name, parent_docs) 833 elif len(name_pieces) == 2: 834 if len(name_pieces[1]) != 1: 835 raise ParseError('Expected identifier after "as"') 836 src_name = parse_dotted_name(name_pieces[0]) 837 var_name = parse_name(name_pieces[1][0]) 838 _import_var_as(src_name, var_name, parent_docs) 839 else: 840 raise ParseError('Multiple "as" tokens in import')
    841
    842 -def process_from_import(line, parent_docs, prev_line_doc, lineno, 843 comments, decorators, encoding):
    844 if not isinstance(parent_docs[-1], NamespaceDoc): return 845 846 pieces = split_on(line[1:], (token.NAME, 'import')) 847 if len(pieces) != 2 or not pieces[0] or not pieces[1]: 848 raise ParseError("Bad from-import") 849 lhs, rhs = pieces 850 851 # The RHS might be parenthasized, as specified by PEP 328: 852 # http://www.python.org/peps/pep-0328.html 853 if (len(rhs) == 1 and isinstance(rhs[0], list) and 854 rhs[0][0] == (token.OP, '(') and rhs[0][-1] == (token.OP, ')')): 855 rhs = rhs[0][1:-1] 856 857 # >>> from __future__ import nested_scopes 858 if lhs == [(token.NAME, '__future__')]: 859 return 860 861 # >>> from sys import * 862 elif rhs == [(token.OP, '*')]: 863 src_name = parse_dotted_name(lhs) 864 _process_fromstar_import(src_name, parent_docs) 865 866 # >>> from os.path import join, split 867 else: 868 # Allow relative imports in this case, as per PEP 328 869 src_name = parse_dotted_name(lhs, 870 parent_name=parent_docs[-1].canonical_name) 871 parts = split_on(rhs, (token.OP, ',')) 872 for part in parts: 873 # from m import x 874 if len(part) == 1: 875 var_name = parse_name(part[0]) 876 _import_var_as(DottedName(src_name, var_name), 877 var_name, parent_docs) 878 879 # from m import x as y 880 elif len(part) == 3 and part[1] == (token.NAME, 'as'): 881 orig_name = parse_name(part[0]) 882 var_name = parse_name(part[2]) 883 _import_var_as(DottedName(src_name, orig_name), 884 var_name, parent_docs) 885 886 else: 887 ParseError("Bad from-import")
    888
    889 -def _process_fromstar_import(src, parent_docs):
    890 """ 891 Handle a statement of the form: 892 >>> from <src> import * 893 894 If L{IMPORT_HANDLING} is C{'parse'}, then first try to parse 895 the module C{M{<src>}}, and copy all of its exported variables 896 to C{parent_docs[-1]}. 897 898 Otherwise, try to determine the names of the variables exported by 899 C{M{<src>}}, and create a new variable for each export. If 900 L{IMPORT_STAR_HANDLING} is C{'parse'}, then the list of exports if 901 found by parsing C{M{<src>}}; if it is C{'introspect'}, then the 902 list of exports is found by importing and introspecting 903 C{M{<src>}}. 904 """ 905 # This is redundant: already checked by caller. 906 if not isinstance(parent_docs[-1], NamespaceDoc): return 907 908 # If src is package-local, then convert it to a global name. 909 src = _global_name(src, parent_docs) 910 911 # Record the import 912 parent_docs[0].imports.append(src) # mark that it's .*?? 913 914 # [xx] add check for if we already have the source docs in our 915 # cache?? 916 917 if (IMPORT_HANDLING == 'parse' or 918 IMPORT_STAR_HANDLING == 'parse'): # [xx] is this ok? 919 try: module_doc = _find(src) 920 except ImportError: module_doc = None 921 if isinstance(module_doc, ModuleDoc): 922 for name, imp_var in module_doc.variables.items(): 923 # [xx] this is not exactly correct, but close. It 924 # does the wrong thing if a __var__ is explicitly 925 # listed in __all__. 926 if (imp_var.is_public and 927 not (name.startswith('__') and name.endswith('__'))): 928 var_doc = _add_import_var(DottedName(src, name), name, 929 parent_docs[-1]) 930 if IMPORT_HANDLING == 'parse': 931 var_doc.value = imp_var.value 932 933 # If we got here, then either IMPORT_HANDLING='link' or we 934 # failed to parse the `src` module. 935 if IMPORT_STAR_HANDLING == 'introspect': 936 try: module = __import__(str(src), {}, {}, [0]) 937 except: return # We couldn't import it. 938 if module is None: return # We couldn't import it. 939 if hasattr(module, '__all__'): 940 names = list(module.__all__) 941 else: 942 names = [n for n in dir(module) if not n.startswith('_')] 943 for name in names: 944 _add_import_var(DottedName(src, name), name, parent_docs[-1])
    945
    946 -def _import_var(name, parent_docs):
    947 """ 948 Handle a statement of the form: 949 >>> import <name> 950 951 If L{IMPORT_HANDLING} is C{'parse'}, then first try to find 952 the value by parsing; and create an appropriate variable in 953 parentdoc. 954 955 Otherwise, add a variable for the imported variable. (More than 956 one variable may be created for cases like C{'import a.b'}, where 957 we need to create a variable C{'a'} in parentdoc containing a 958 proxy module; and a variable C{'b'} in the proxy module. 959 """ 960 # This is redundant: already checked by caller. 961 if not isinstance(parent_docs[-1], NamespaceDoc): return 962 963 # If name is package-local, then convert it to a global name. 964 src = _global_name(name, parent_docs) 965 src_prefix = src[:len(src)-len(name)] 966 967 # Record the import 968 parent_docs[0].imports.append(name) 969 970 # [xx] add check for if we already have the source docs in our 971 # cache?? 972 973 if IMPORT_HANDLING == 'parse': 974 # Check to make sure that we can actually find the value. 975 try: val_doc = _find(src) 976 except ImportError: val_doc = None 977 if val_doc is not None: 978 # We found it; but it's not the value itself we want to 979 # import, but the module containing it; so import that 980 # module (=top_mod) and create a variable for it. 981 top_mod = src_prefix+name[0] 982 var_doc = _add_import_var(top_mod, name[0], parent_docs[-1]) 983 var_doc.value = _find(DottedName(name[0])) 984 return 985 986 # If we got here, then either IMPORT_HANDLING='link', or we 987 # did not successfully find the value's docs by parsing; use 988 # a variable with an UNKNOWN value. 989 990 # Create any necessary intermediate proxy module values. 991 container = parent_docs[-1] 992 for i, identifier in enumerate(name[:-1]): 993 if (identifier not in container.variables or 994 not isinstance(container.variables[identifier], ModuleDoc)): 995 var_doc = _add_import_var(name[:i+1], identifier, container) 996 var_doc.value = ModuleDoc(variables={}, sort_spec=[], 997 proxy_for=src_prefix+name[:i+1], 998 submodules={}, 999 docs_extracted_by='parser') 1000 container = container.variables[identifier].value 1001 1002 # Add the variable to the container. 1003 _add_import_var(src, name[-1], container)
    1004
    1005 -def _import_var_as(src, name, parent_docs):
    1006 """ 1007 Handle a statement of the form: 1008 >>> import src as name 1009 1010 If L{IMPORT_HANDLING} is C{'parse'}, then first try to find 1011 the value by parsing; and create an appropriate variable in 1012 parentdoc. 1013 1014 Otherwise, create a variables with its C{imported_from} attribute 1015 pointing to the imported object. 1016 """ 1017 # This is redundant: already checked by caller. 1018 if not isinstance(parent_docs[-1], NamespaceDoc): return 1019 1020 # If src is package-local, then convert it to a global name. 1021 src = _global_name(src, parent_docs) 1022 1023 # Record the import 1024 parent_docs[0].imports.append(src) 1025 1026 if IMPORT_HANDLING == 'parse': 1027 # Parse the value and create a variable for it. 1028 try: val_doc = _find(src) 1029 except ImportError: val_doc = None 1030 if val_doc is not None: 1031 var_doc = VariableDoc(name=name, value=val_doc, 1032 is_imported=True, is_alias=False, 1033 imported_from=src, 1034 docs_extracted_by='parser') 1035 set_variable(parent_docs[-1], var_doc) 1036 return 1037 1038 # If we got here, then either IMPORT_HANDLING='link', or we 1039 # did not successfully find the value's docs by parsing; use a 1040 # variable with a proxy value. 1041 _add_import_var(src, name, parent_docs[-1])
    1042
    1043 -def _add_import_var(src, name, container):
    1044 """ 1045 Add a new imported variable named C{name} to C{container}, with 1046 C{imported_from=src}. 1047 """ 1048 var_doc = VariableDoc(name=name, is_imported=True, is_alias=False, 1049 imported_from=src, docs_extracted_by='parser') 1050 set_variable(container, var_doc) 1051 return var_doc
    1052
    1053 -def _global_name(name, parent_docs):
    1054 """ 1055 If the given name is package-local (relative to the current 1056 context, as determined by C{parent_docs}), then convert it 1057 to a global name. 1058 """ 1059 # Get the containing package from parent_docs. 1060 if parent_docs[0].is_package: 1061 package = parent_docs[0] 1062 else: 1063 package = parent_docs[0].package 1064 1065 # Check each package (from closest to furthest) to see if it 1066 # contains a module named name[0]; if so, then treat `name` as 1067 # relative to that package. 1068 while package not in (None, UNKNOWN): 1069 try: 1070 fp = imp.find_module(name[0], package.path)[0] 1071 if fp is not None: fp.close() 1072 except ImportError: 1073 # No submodule found here; try the next package up. 1074 package = package.package 1075 continue 1076 # A submodule was found; return its name. 1077 return package.canonical_name + name 1078 1079 # We didn't find any package containing `name`; so just return 1080 # `name` as-is. 1081 return name
    1082 1083 #///////////////////////////////////////////////////////////////// 1084 # Line handler: assignment 1085 #///////////////////////////////////////////////////////////////// 1086
    1087 -def process_assignment(line, parent_docs, prev_line_doc, lineno, 1088 comments, decorators, encoding):
    1089 # Divide the assignment statement into its pieces. 1090 pieces = split_on(line, (token.OP, '=')) 1091 1092 lhs_pieces = pieces[:-1] 1093 rhs = pieces[-1] 1094 1095 # Decide whether the variable is an instance variable or not. 1096 # If it's an instance var, then discard the value. 1097 is_instvar = lhs_is_instvar(lhs_pieces, parent_docs) 1098 1099 # if it's not an instance var, and we're not in a namespace, 1100 # then it's just a local var -- so ignore it. 1101 if not (is_instvar or isinstance(parent_docs[-1], NamespaceDoc)): 1102 return None 1103 1104 # Evaluate the right hand side. 1105 if not is_instvar: 1106 rhs_val, is_alias = rhs_to_valuedoc(rhs, parent_docs) 1107 else: 1108 rhs_val, is_alias = UNKNOWN, False 1109 1110 # Assign the right hand side value to each left hand side. 1111 # (Do the rightmost assignment first) 1112 lhs_pieces.reverse() 1113 for lhs in lhs_pieces: 1114 # Try treating the LHS as a simple dotted name. 1115 try: lhs_name = parse_dotted_name(lhs) 1116 except: lhs_name = None 1117 if lhs_name is not None: 1118 lhs_parent = get_lhs_parent(lhs_name, parent_docs) 1119 if lhs_parent is None: continue 1120 1121 # Skip a special class variable. 1122 if lhs_name[-1] == '__slots__': 1123 continue 1124 1125 # Create the VariableDoc. 1126 var_doc = VariableDoc(name=lhs_name[-1], value=rhs_val, 1127 is_imported=False, is_alias=is_alias, 1128 is_instvar=is_instvar, 1129 docs_extracted_by='parser') 1130 # Extract a docstring from the comments, when present, 1131 # but only if there's a single LHS. 1132 if len(lhs_pieces) == 1: 1133 add_docstring_from_comments(var_doc, comments) 1134 1135 # Assign the variable to the containing namespace, 1136 # *unless* the variable is an instance variable 1137 # without a comment docstring. In that case, we'll 1138 # only want to add it if we later discover that it's 1139 # followed by a variable docstring. If it is, then 1140 # process_docstring will take care of adding it to the 1141 # containing clas. (This is a little hackish, but 1142 # unfortunately is necessary because we won't know if 1143 # this assignment line is followed by a docstring 1144 # until later.) 1145 if (not is_instvar) or comments: 1146 set_variable(lhs_parent, var_doc, True) 1147 1148 # If it's the only var, then return the VarDoc for use 1149 # as the new `prev_line_doc`. 1150 if (len(lhs_pieces) == 1 and 1151 (len(lhs_name) == 1 or is_instvar)): 1152 return var_doc 1153 1154 # Otherwise, the LHS must be a complex expression; use 1155 # dotted_names_in() to decide what variables it contains, 1156 # and create VariableDoc's for all of them (with UNKNOWN 1157 # value). 1158 else: 1159 for lhs_name in dotted_names_in(lhs_pieces): 1160 lhs_parent = get_lhs_parent(lhs_name, parent_docs) 1161 if lhs_parent is None: continue 1162 var_doc = VariableDoc(name=lhs_name[-1], 1163 is_imported=False, 1164 is_alias=is_alias, 1165 is_instvar=is_instvar, 1166 docs_extracted_by='parser') 1167 set_variable(lhs_parent, var_doc, True) 1168 1169 # If we have multiple left-hand-sides, then all but the 1170 # rightmost one are considered aliases. 1171 is_alias = True
    1172 1173
    1174 -def lhs_is_instvar(lhs_pieces, parent_docs):
    1175 if not isinstance(parent_docs[-1], RoutineDoc): 1176 return False 1177 # make sure that lhs_pieces is <self>.<name>, where <self> is 1178 # the name of the first arg to the containing routinedoc, and 1179 # <name> is a simple name. 1180 posargs = parent_docs[-1].posargs 1181 if posargs is UNKNOWN: return False 1182 if not (len(lhs_pieces)==1 and len(posargs) > 0 and 1183 len(lhs_pieces[0]) == 3 and 1184 lhs_pieces[0][0] == (token.NAME, posargs[0]) and 1185 lhs_pieces[0][1] == (token.OP, '.') and 1186 lhs_pieces[0][2][0] == token.NAME): 1187 return False 1188 # Make sure we're in an instance method, and not a 1189 # module-level function. 1190 for i in range(len(parent_docs)-1, -1, -1): 1191 if isinstance(parent_docs[i], ClassDoc): 1192 return True 1193 elif parent_docs[i] != parent_docs[-1]: 1194 return False 1195 return False
    1196
    1197 -def rhs_to_valuedoc(rhs, parent_docs):
    1198 # Dotted variable: 1199 try: 1200 rhs_name = parse_dotted_name(rhs) 1201 rhs_val = lookup_value(rhs_name, parent_docs) 1202 if rhs_val is not None and rhs_val is not UNKNOWN: 1203 return rhs_val, True 1204 except ParseError: 1205 pass 1206 1207 # Decorators: 1208 if (len(rhs)==2 and rhs[0][0] == token.NAME and 1209 isinstance(rhs[1], list)): 1210 arg_val, _ = rhs_to_valuedoc(rhs[1][1:-1], parent_docs) 1211 if isinstance(arg_val, RoutineDoc): 1212 doc = apply_decorator(DottedName(rhs[0][1]), arg_val) 1213 doc.canonical_name = UNKNOWN 1214 doc.parse_repr = pp_toktree(rhs) 1215 return doc, False 1216 1217 # Nothing else to do: make a val with the source as its repr. 1218 return GenericValueDoc(parse_repr=pp_toktree(rhs), toktree=rhs, 1219 defining_module=parent_docs[0], 1220 docs_extracted_by='parser'), False
    1221
    1222 -def get_lhs_parent(lhs_name, parent_docs):
    1223 assert isinstance(lhs_name, DottedName) 1224 1225 # For instance vars inside an __init__ method: 1226 if isinstance(parent_docs[-1], RoutineDoc): 1227 for i in range(len(parent_docs)-1, -1, -1): 1228 if isinstance(parent_docs[i], ClassDoc): 1229 return parent_docs[i] 1230 else: 1231 raise ValueError("%r is not a namespace or method" % 1232 parent_docs[-1]) 1233 1234 # For local variables: 1235 if len(lhs_name) == 1: 1236 return parent_docs[-1] 1237 1238 # For non-local variables: 1239 return lookup_value(lhs_name.container(), parent_docs)
    1240 1241 #///////////////////////////////////////////////////////////////// 1242 # Line handler: single-line blocks 1243 #///////////////////////////////////////////////////////////////// 1244
    1245 -def process_one_line_block(line, parent_docs, prev_line_doc, lineno, 1246 comments, decorators, encoding):
    1247 """ 1248 The line handler for single-line blocks, such as: 1249 1250 >>> def f(x): return x*2 1251 1252 This handler calls L{process_line} twice: once for the tokens 1253 up to and including the colon, and once for the remaining 1254 tokens. The comment docstring is applied to the first line 1255 only. 1256 @return: C{None} 1257 """ 1258 i = line.index((token.OP, ':')) 1259 doc1 = process_line(line[:i+1], parent_docs, prev_line_doc, 1260 lineno, comments, decorators, encoding) 1261 doc2 = process_line(line[i+1:], parent_docs+[doc1], 1262 doc1, lineno, None, [], encoding) 1263 return doc1
    1264 1265 #///////////////////////////////////////////////////////////////// 1266 # Line handler: semicolon-separated statements 1267 #///////////////////////////////////////////////////////////////// 1268
    1269 -def process_multi_stmt(line, parent_docs, prev_line_doc, lineno, 1270 comments, decorators, encoding):
    1271 """ 1272 The line handler for semicolon-separated statements, such as: 1273 1274 >>> x=1; y=2; z=3 1275 1276 This handler calls L{process_line} once for each statement. 1277 The comment docstring is not passed on to any of the 1278 sub-statements. 1279 @return: C{None} 1280 """ 1281 for statement in split_on(line, (token.OP, ';')): 1282 if not statement: continue 1283 doc = process_line(statement, parent_docs, prev_line_doc, 1284 lineno, None, decorators, encoding) 1285 prev_line_doc = doc 1286 decorators = [] 1287 return None
    1288 1289 #///////////////////////////////////////////////////////////////// 1290 # Line handler: delete statements 1291 #///////////////////////////////////////////////////////////////// 1292
    1293 -def process_del(line, parent_docs, prev_line_doc, lineno, 1294 comments, decorators, encoding):
    1295 """ 1296 The line handler for delete statements, such as: 1297 1298 >>> del x, y.z 1299 1300 This handler calls L{del_variable} for each dotted variable in 1301 the variable list. The variable list may be nested. Complex 1302 expressions in the variable list (such as C{x[3]}) are ignored. 1303 @return: C{None} 1304 """ 1305 # If we're not in a namespace, then ignore it. 1306 parent_doc = parent_docs[-1] 1307 if not isinstance(parent_doc, NamespaceDoc): return 1308 1309 var_list = split_on(line[1:], (token.OP, ',')) 1310 for var_name in dotted_names_in(var_list): 1311 del_variable(parent_docs[-1], var_name) 1312 1313 return None
    1314 1315 #///////////////////////////////////////////////////////////////// 1316 # Line handler: docstrings 1317 #///////////////////////////////////////////////////////////////// 1318
    1319 -def process_docstring(line, parent_docs, prev_line_doc, lineno, 1320 comments, decorators, encoding):
    1321 """ 1322 The line handler for bare string literals. If 1323 C{prev_line_doc} is not C{None}, then the string literal is 1324 added to that C{APIDoc} as a docstring. If it already has a 1325 docstring (from comment docstrings), then the new docstring 1326 will be appended to the old one. 1327 """ 1328 if prev_line_doc is None: return 1329 docstring = parse_string(line) 1330 1331 # If the docstring is a str, then convert it to unicode. 1332 # According to a strict reading of PEP 263, this might not be the 1333 # right thing to do; but it will almost always be what the 1334 # module's author intended. 1335 if isinstance(docstring, str): 1336 try: 1337 docstring = docstring.decode(encoding) 1338 except UnicodeDecodeError: 1339 # If decoding failed, then fall back on using 1340 # decode_with_backslashreplace, which will map e.g. 1341 # "\xe9" -> u"\\xe9". 1342 docstring = decode_with_backslashreplace(docstring) 1343 log.warning("While parsing %s: docstring is not a unicode " 1344 "string, but it contains non-ascii data." % 1345 prev_line_doc.canonical_name) 1346 1347 # If the modified APIDoc is an instance variable, and it has 1348 # not yet been added to its class's C{variables} list, 1349 # then add it now. This is done here, rather than in the 1350 # process_assignment() call that created the variable, because 1351 # we only want to add instance variables if they have an 1352 # associated docstring. (For more info, see the comment above 1353 # the set_variable() call in process_assignment().) 1354 added_instvar = False 1355 if (isinstance(prev_line_doc, VariableDoc) and 1356 prev_line_doc.is_instvar and 1357 prev_line_doc.docstring in (None, UNKNOWN)): 1358 for i in range(len(parent_docs)-1, -1, -1): 1359 if isinstance(parent_docs[i], ClassDoc): 1360 set_variable(parent_docs[i], prev_line_doc, True) 1361 added_instvar = True 1362 break 1363 1364 if prev_line_doc.docstring not in (None, UNKNOWN): 1365 log.warning("%s has both a comment-docstring and a normal " 1366 "(string) docstring; ignoring the comment-" 1367 "docstring." % prev_line_doc.canonical_name) 1368 1369 prev_line_doc.docstring = docstring 1370 prev_line_doc.docstring_lineno = lineno 1371 1372 # If the modified APIDoc is an instance variable, and we added it 1373 # to the class's variables list here, then it still needs to be 1374 # grouped too; so return it for use as the new "prev_line_doc." 1375 if added_instvar: 1376 return prev_line_doc
    1377 1378 1379 #///////////////////////////////////////////////////////////////// 1380 # Line handler: function declarations 1381 #///////////////////////////////////////////////////////////////// 1382
    1383 -def process_funcdef(line, parent_docs, prev_line_doc, lineno, 1384 comments, decorators, encoding):
    1385 """ 1386 The line handler for function declaration lines, such as: 1387 1388 >>> def f(a, b=22, (c,d)): 1389 1390 This handler creates and initializes a new C{VariableDoc} 1391 containing a C{RoutineDoc}, adds the C{VariableDoc} to the 1392 containing namespace, and returns the C{RoutineDoc}. 1393 """ 1394 # Check syntax. 1395 if len(line) != 4 or line[3] != (token.OP, ':'): 1396 raise ParseError("Bad function definition line") 1397 1398 # If we're not in a namespace, then ignore it. 1399 parent_doc = parent_docs[-1] 1400 if not isinstance(parent_doc, NamespaceDoc): return 1401 1402 # Get the function's name 1403 func_name = parse_name(line[1]) 1404 canonical_name = DottedName(parent_doc.canonical_name, func_name) 1405 1406 # Create the function's RoutineDoc. 1407 func_doc = RoutineDoc(canonical_name=canonical_name, 1408 defining_module=parent_docs[0], 1409 lineno=lineno, docs_extracted_by='parser') 1410 1411 # Process the signature. 1412 init_arglist(func_doc, line[2]) 1413 1414 # If the preceeding comment includes a docstring, then add it. 1415 add_docstring_from_comments(func_doc, comments) 1416 1417 # Apply any decorators. 1418 func_doc.decorators = [pp_toktree(deco[1:]) for deco in decorators] 1419 decorators.reverse() 1420 for decorator in decorators: 1421 try: 1422 deco_name = parse_dotted_name(decorator[1:]) 1423 except ParseError: 1424 deco_name = None 1425 if func_doc.canonical_name is not UNKNOWN: 1426 deco_repr = '%s(%s)' % (pp_toktree(decorator[1:]), 1427 func_doc.canonical_name) 1428 elif func_doc.parse_repr not in (None, UNKNOWN): 1429 # [xx] this case should be improved.. when will func_doc 1430 # have a known parse_repr?? 1431 deco_repr = '%s(%s)' % (pp_toktree(decorator[1:]), 1432 func_doc.parse_repr) 1433 else: 1434 deco_repr = UNKNOWN 1435 func_doc = apply_decorator(deco_name, func_doc) 1436 func_doc.parse_repr = deco_repr 1437 # [XX] Is there a reson the following should be done? It 1438 # causes the grouping code to break. Presumably the canonical 1439 # name should remain valid if we're just applying a standard 1440 # decorator. 1441 #func_doc.canonical_name = UNKNOWN 1442 1443 # Add a variable to the containing namespace. 1444 var_doc = VariableDoc(name=func_name, value=func_doc, 1445 is_imported=False, is_alias=False, 1446 docs_extracted_by='parser') 1447 set_variable(parent_doc, var_doc) 1448 1449 # Return the new ValueDoc. 1450 return func_doc
    1451
    1452 -def apply_decorator(decorator_name, func_doc):
    1453 # [xx] what if func_doc is not a RoutineDoc? 1454 if decorator_name == DottedName('staticmethod'): 1455 return StaticMethodDoc(**func_doc.__dict__) 1456 elif decorator_name == DottedName('classmethod'): 1457 return ClassMethodDoc(**func_doc.__dict__) 1458 elif DEFAULT_DECORATOR_BEHAVIOR == 'transparent': 1459 return func_doc.__class__(**func_doc.__dict__) # make a copy. 1460 elif DEFAULT_DECORATOR_BEHAVIOR == 'opaque': 1461 return GenericValueDoc(docs_extracted_by='parser') 1462 else: 1463 raise ValueError, 'Bad value for DEFAULT_DECORATOR_BEHAVIOR'
    1464
    1465 -def init_arglist(func_doc, arglist):
    1466 if not isinstance(arglist, list) or arglist[0] != (token.OP, '('): 1467 raise ParseError("Bad argument list") 1468 1469 # Initialize to defaults. 1470 func_doc.posargs = [] 1471 func_doc.posarg_defaults = [] 1472 func_doc.vararg = None 1473 func_doc.kwarg = None 1474 1475 # Divide the arglist into individual args. 1476 args = split_on(arglist[1:-1], (token.OP, ',')) 1477 1478 # Keyword argument. 1479 if args and args[-1][0] == (token.OP, '**'): 1480 if len(args[-1]) != 2 or args[-1][1][0] != token.NAME: 1481 raise ParseError("Expected name after ** in argument list") 1482 func_doc.kwarg = args[-1][1][1] 1483 args.pop() 1484 1485 # Vararg argument. 1486 if args and args[-1][0] == (token.OP, '*'): 1487 if len(args[-1]) != 2 or args[-1][1][0] != token.NAME: 1488 raise ParseError("Expected name after * in argument list") 1489 func_doc.vararg = args[-1][1][1] 1490 args.pop() 1491 1492 # Positional arguments. 1493 for arg in args: 1494 func_doc.posargs.append(parse_funcdef_arg(arg[0])) 1495 if len(arg) == 1: 1496 func_doc.posarg_defaults.append(None) 1497 elif arg[1] != (token.OP, '=') or len(arg) == 2: 1498 raise ParseError("Bad argument list") 1499 else: 1500 default_repr = pp_toktree(arg[2:], 'tight') 1501 default_val = GenericValueDoc(parse_repr=default_repr, 1502 docs_extracted_by='parser') 1503 func_doc.posarg_defaults.append(default_val)
    1504 1505 #///////////////////////////////////////////////////////////////// 1506 # Line handler: class declarations 1507 #///////////////////////////////////////////////////////////////// 1508
    1509 -def process_classdef(line, parent_docs, prev_line_doc, lineno, 1510 comments, decorators, encoding):
    1511 """ 1512 The line handler for class declaration lines, such as: 1513 1514 >>> class Foo(Bar, Baz): 1515 1516 This handler creates and initializes a new C{VariableDoc} 1517 containing a C{ClassDoc}, adds the C{VariableDoc} to the 1518 containing namespace, and returns the C{ClassDoc}. 1519 """ 1520 # Check syntax 1521 if len(line)<3 or len(line)>4 or line[-1] != (token.OP, ':'): 1522 raise ParseError("Bad class definition line") 1523 1524 # If we're not in a namespace, then ignore it. 1525 parent_doc = parent_docs[-1] 1526 if not isinstance(parent_doc, NamespaceDoc): return 1527 1528 # Get the class's name 1529 class_name = parse_name(line[1]) 1530 canonical_name = DottedName(parent_doc.canonical_name, class_name) 1531 1532 # Create the class's ClassDoc & VariableDoc. 1533 class_doc = ClassDoc(variables={}, sort_spec=[], 1534 bases=[], subclasses=[], 1535 canonical_name=canonical_name, 1536 defining_module=parent_docs[0], 1537 docs_extracted_by='parser') 1538 var_doc = VariableDoc(name=class_name, value=class_doc, 1539 is_imported=False, is_alias=False, 1540 docs_extracted_by='parser') 1541 1542 # Add the bases. 1543 if len(line) == 4: 1544 if (not isinstance(line[2], list) or 1545 line[2][0] != (token.OP, '(')): 1546 raise ParseError("Expected base list") 1547 try: 1548 for base_name in parse_classdef_bases(line[2]): 1549 class_doc.bases.append(find_base(base_name, parent_docs)) 1550 except ParseError, e: 1551 log.warning("Unable to extract the base list for %s: %s" % 1552 (canonical_name, e)) 1553 class_doc.bases = UNKNOWN 1554 else: 1555 class_doc.bases = [] 1556 1557 # Register ourselves as a subclass to our bases. 1558 if class_doc.bases is not UNKNOWN: 1559 for basedoc in class_doc.bases: 1560 if isinstance(basedoc, ClassDoc): 1561 # This test avoids that a subclass gets listed twice when 1562 # both introspection and parsing. 1563 # [XXX] This check only works because currently parsing is 1564 # always performed just after introspection of the same 1565 # class. A more complete fix shuld be independent from 1566 # calling order; probably the subclasses list should be 1567 # replaced by a ClassDoc set or a {name: ClassDoc} mapping. 1568 if (basedoc.subclasses 1569 and basedoc.subclasses[-1].canonical_name 1570 != class_doc.canonical_name): 1571 basedoc.subclasses.append(class_doc) 1572 1573 # If the preceeding comment includes a docstring, then add it. 1574 add_docstring_from_comments(class_doc, comments) 1575 1576 # Add the VariableDoc to our container. 1577 set_variable(parent_doc, var_doc) 1578 1579 return class_doc
    1580
    1581 -def _proxy_base(**attribs):
    1582 return ClassDoc(variables={}, sort_spec=[], bases=[], subclasses=[], 1583 docs_extracted_by='parser', **attribs)
    1584
    1585 -def find_base(name, parent_docs):
    1586 assert isinstance(name, DottedName) 1587 1588 # Find the variable containing the base. 1589 base_var = lookup_variable(name, parent_docs) 1590 if base_var is None: 1591 # If we didn't find it, then it must have been imported. 1592 # First, check if it looks like it's contained in any 1593 # known imported variable: 1594 if len(name) > 1: 1595 src = lookup_name(name[0], parent_docs) 1596 if (src is not None and 1597 src.imported_from not in (None, UNKNOWN)): 1598 base_src = DottedName(src.imported_from, name[1:]) 1599 base_var = VariableDoc(name=name[-1], is_imported=True, 1600 is_alias=False, imported_from=base_src, 1601 docs_extracted_by='parser') 1602 # Otherwise, it must have come from an "import *" statement 1603 # (or from magic, such as direct manipulation of the module's 1604 # dictionary), so we don't know where it came from. So 1605 # there's nothing left but to use an empty proxy. 1606 if base_var is None: 1607 return _proxy_base(parse_repr=str(name)) 1608 #raise ParseError("Could not find %s" % name) 1609 1610 # If the variable has a value, return that value. 1611 if base_var.value is not UNKNOWN: 1612 return base_var.value 1613 1614 # Otherwise, if BASE_HANDLING is 'parse', try parsing the docs for 1615 # the base class; if that fails, or if BASE_HANDLING is 'link', 1616 # just make a proxy object. 1617 if base_var.imported_from not in (None, UNKNOWN): 1618 if BASE_HANDLING == 'parse': 1619 old_sys_path = sys.path 1620 try: 1621 dirname = os.path.split(parent_docs[0].filename)[0] 1622 sys.path = [dirname] + sys.path 1623 try: 1624 return parse_docs(name=str(base_var.imported_from)) 1625 except ParseError: 1626 log.info('Unable to parse base', base_var.imported_from) 1627 except ImportError: 1628 log.info('Unable to find base', base_var.imported_from) 1629 finally: 1630 sys.path = old_sys_path 1631 1632 # Either BASE_HANDLING='link' or parsing the base class failed; 1633 # return a proxy value for the base class. 1634 return _proxy_base(proxy_for=base_var.imported_from) 1635 else: 1636 return _proxy_base(parse_repr=str(name))
    1637 1638 #///////////////////////////////////////////////////////////////// 1639 #{ Parsing 1640 #///////////////////////////////////////////////////////////////// 1641
    1642 -def dotted_names_in(elt_list):
    1643 """ 1644 Return a list of all simple dotted names in the given 1645 expression. 1646 """ 1647 names = [] 1648 while elt_list: 1649 elt = elt_list.pop() 1650 if len(elt) == 1 and isinstance(elt[0], list): 1651 # Nested list: process the contents 1652 elt_list.extend(split_on(elt[0][1:-1], (token.OP, ','))) 1653 else: 1654 try: 1655 names.append(parse_dotted_name(elt)) 1656 except ParseError: 1657 pass # complex expression -- ignore 1658 return names
    1659
    1660 -def parse_name(elt, strip_parens=False):
    1661 """ 1662 If the given token tree element is a name token, then return 1663 that name as a string. Otherwise, raise ParseError. 1664 @param strip_parens: If true, then if elt is a single name 1665 enclosed in parenthases, then return that name. 1666 """ 1667 if strip_parens and isinstance(elt, list): 1668 while (isinstance(elt, list) and len(elt) == 3 and 1669 elt[0] == (token.OP, '(') and 1670 elt[-1] == (token.OP, ')')): 1671 elt = elt[1] 1672 if isinstance(elt, list) or elt[0] != token.NAME: 1673 raise ParseError("Bad name") 1674 return elt[1]
    1675
    1676 -def parse_dotted_name(elt_list, strip_parens=True, parent_name=None):
    1677 """ 1678 @param parent_name: canonical name of referring module, to resolve 1679 relative imports. 1680 @type parent_name: L{DottedName} 1681 @bug: does not handle 'x.(y).z' 1682 """ 1683 if len(elt_list) == 0: raise ParseError("Bad dotted name") 1684 1685 # Handle ((x.y).z). (If the contents of the parens include 1686 # anything other than dotted names, such as (x,y), then we'll 1687 # catch it below and raise a ParseError. 1688 while (isinstance(elt_list[0], list) and 1689 len(elt_list[0]) >= 3 and 1690 elt_list[0][0] == (token.OP, '(') and 1691 elt_list[0][-1] == (token.OP, ')')): 1692 elt_list[:1] = elt_list[0][1:-1] 1693 1694 # Convert a relative import into an absolute name. 1695 prefix_name = None 1696 if parent_name is not None and elt_list[0][-1] == '.': 1697 items = 1 1698 while len(elt_list) > items and elt_list[items][-1] == '.': 1699 items += 1 1700 1701 elt_list = elt_list[items:] 1702 prefix_name = parent_name[:-items] 1703 1704 # >>> from . import foo 1705 if not elt_list: 1706 if prefix_name == []: 1707 raise ParseError("Attempted relative import in non-package, " 1708 "or beyond toplevel package") 1709 return prefix_name 1710 1711 if len(elt_list) % 2 != 1: raise ParseError("Bad dotted name") 1712 name = DottedName(parse_name(elt_list[0], True)) 1713 if prefix_name is not None: 1714 name = prefix_name + name 1715 1716 for i in range(2, len(elt_list), 2): 1717 dot, identifier = elt_list[i-1], elt_list[i] 1718 if dot != (token.OP, '.'): 1719 raise ParseError("Bad dotted name") 1720 name = DottedName(name, parse_name(identifier, True)) 1721 return name
    1722
    1723 -def split_on(elt_list, split_tok):
    1724 # [xx] add code to guarantee each elt is non-empty. 1725 result = [[]] 1726 for elt in elt_list: 1727 if elt == split_tok: 1728 if result[-1] == []: raise ParseError("Empty element from split") 1729 result.append([]) 1730 else: 1731 result[-1].append(elt) 1732 if result[-1] == []: result.pop() 1733 return result
    1734
    1735 -def parse_funcdef_arg(elt):
    1736 """ 1737 If the given tree token element contains a valid function 1738 definition argument (i.e., an identifier token or nested list 1739 of identifiers), then return a corresponding string identifier 1740 or nested list of string identifiers. Otherwise, raise a 1741 ParseError. 1742 """ 1743 if isinstance(elt, list): 1744 if elt[0] == (token.OP, '('): 1745 if len(elt) == 3: 1746 return parse_funcdef_arg(elt[1]) 1747 else: 1748 return [parse_funcdef_arg(e) 1749 for e in elt[1:-1] 1750 if e != (token.OP, ',')] 1751 else: 1752 raise ParseError("Bad argument -- expected name or tuple") 1753 elif elt[0] == token.NAME: 1754 return elt[1] 1755 else: 1756 raise ParseError("Bad argument -- expected name or tuple")
    1757
    1758 -def parse_classdef_bases(elt):
    1759 """ 1760 If the given tree token element contains a valid base list 1761 (that contains only dotted names), then return a corresponding 1762 list of L{DottedName}s. Otherwise, raise a ParseError. 1763 1764 @bug: Does not handle either of:: 1765 - class A( (base.in.parens) ): pass 1766 - class B( (lambda:calculated.base)() ): pass 1767 """ 1768 if (not isinstance(elt, list) or 1769 elt[0] != (token.OP, '(')): 1770 raise ParseError("Bad base list") 1771 1772 return [parse_dotted_name(n) 1773 for n in split_on(elt[1:-1], (token.OP, ','))]
    1774 1775 # Used by: base list; 'del'; ...
    1776 -def parse_dotted_name_list(elt_list):
    1777 """ 1778 If the given list of tree token elements contains a 1779 comma-separated list of dotted names, then return a 1780 corresponding list of L{DottedName} objects. Otherwise, raise 1781 ParseError. 1782 """ 1783 names = [] 1784 1785 state = 0 1786 for elt in elt_list: 1787 # State 0 -- Expecting a name, or end of arglist 1788 if state == 0: 1789 # Make sure it's a name 1790 if isinstance(elt, tuple) and elt[0] == token.NAME: 1791 names.append(DottedName(elt[1])) 1792 state = 1 1793 else: 1794 raise ParseError("Expected a name") 1795 # State 1 -- Expecting comma, period, or end of arglist 1796 elif state == 1: 1797 if elt == (token.OP, '.'): 1798 state = 2 1799 elif elt == (token.OP, ','): 1800 state = 0 1801 else: 1802 raise ParseError("Expected '.' or ',' or end of list") 1803 # State 2 -- Continuation of dotted name. 1804 elif state == 2: 1805 if isinstance(elt, tuple) and elt[0] == token.NAME: 1806 names[-1] = DottedName(names[-1], elt[1]) 1807 state = 1 1808 else: 1809 raise ParseError("Expected a name") 1810 if state == 2: 1811 raise ParseError("Expected a name") 1812 return names
    1813
    1814 -def parse_string(elt_list):
    1815 if len(elt_list) == 1 and elt_list[0][0] == token.STRING: 1816 # [xx] use something safer here? But it needs to deal with 1817 # any string type (eg r"foo\bar" etc). 1818 return eval(elt_list[0][1]) 1819 else: 1820 raise ParseError("Expected a string")
    1821 1822 # ['1', 'b', 'c']
    1823 -def parse_string_list(elt_list):
    1824 if (len(elt_list) == 1 and isinstance(elt_list, list) and 1825 elt_list[0][0][1] in ('(', '[')): 1826 elt_list = elt_list[0][1:-1] 1827 1828 string_list = [] 1829 for string_elt in split_on(elt_list, (token.OP, ',')): 1830 string_list.append(parse_string(string_elt)) 1831 1832 return string_list
    1833 1834 #///////////////////////////////////////////////////////////////// 1835 #{ Variable Manipulation 1836 #///////////////////////////////////////////////////////////////// 1837
    1838 -def set_variable(namespace, var_doc, preserve_docstring=False):
    1839 """ 1840 Add var_doc to namespace. If namespace already contains a 1841 variable with the same name, then discard the old variable. If 1842 C{preserve_docstring} is true, then keep the old variable's 1843 docstring when overwriting a variable. 1844 """ 1845 # Choose which dictionary we'll be storing the variable in. 1846 if not isinstance(namespace, NamespaceDoc): 1847 return 1848 1849 # This happens when the class definition has not been parsed, e.g. in 1850 # sf bug #1693253 on ``Exception.x = y`` 1851 if namespace.sort_spec is UNKNOWN: 1852 namespace.sort_spec = namespace.variables.keys() 1853 1854 # If we already have a variable with this name, then remove the 1855 # old VariableDoc from the sort_spec list; and if we gave its 1856 # value a canonical name, then delete it. 1857 if var_doc.name in namespace.variables: 1858 namespace.sort_spec.remove(var_doc.name) 1859 old_var_doc = namespace.variables[var_doc.name] 1860 if (old_var_doc.is_alias == False and 1861 old_var_doc.value is not UNKNOWN): 1862 old_var_doc.value.canonical_name = UNKNOWN 1863 if (preserve_docstring and var_doc.docstring in (None, UNKNOWN) and 1864 old_var_doc.docstring not in (None, UNKNOWN)): 1865 var_doc.docstring = old_var_doc.docstring 1866 var_doc.docstring_lineno = old_var_doc.docstring_lineno 1867 # Add the variable to the namespace. 1868 namespace.variables[var_doc.name] = var_doc 1869 namespace.sort_spec.append(var_doc.name) 1870 assert var_doc.container is UNKNOWN 1871 var_doc.container = namespace
    1872
    1873 -def del_variable(namespace, name):
    1874 if not isinstance(namespace, NamespaceDoc): 1875 return 1876 1877 if name[0] in namespace.variables: 1878 if len(name) == 1: 1879 var_doc = namespace.variables[name[0]] 1880 namespace.sort_spec.remove(name[0]) 1881 del namespace.variables[name[0]] 1882 if not var_doc.is_alias and var_doc.value is not UNKNOWN: 1883 var_doc.value.canonical_name = UNKNOWN 1884 else: 1885 del_variable(namespace.variables[name[0]].value, name[1:])
    1886 1887 #///////////////////////////////////////////////////////////////// 1888 #{ Name Lookup 1889 #///////////////////////////////////////////////////////////////// 1890
    1891 -def lookup_name(identifier, parent_docs):
    1892 """ 1893 Find and return the documentation for the variable named by 1894 the given identifier. 1895 1896 @rtype: L{VariableDoc} or C{None} 1897 """ 1898 # We need to check 3 namespaces: locals, globals, and builtins. 1899 # Note that this is true even if we're in a version of python with 1900 # nested scopes, because nested scope lookup does not apply to 1901 # nested class definitions, and we're not worried about variables 1902 # in nested functions. 1903 if not isinstance(identifier, basestring): 1904 raise TypeError('identifier must be a string') 1905 1906 # Locals 1907 if isinstance(parent_docs[-1], NamespaceDoc): 1908 if identifier in parent_docs[-1].variables: 1909 return parent_docs[-1].variables[identifier] 1910 1911 # Globals (aka the containing module) 1912 if isinstance(parent_docs[0], NamespaceDoc): 1913 if identifier in parent_docs[0].variables: 1914 return parent_docs[0].variables[identifier] 1915 1916 # Builtins 1917 builtins = epydoc.docintrospecter.introspect_docs(__builtin__) 1918 if isinstance(builtins, NamespaceDoc): 1919 if identifier in builtins.variables: 1920 return builtins.variables[identifier] 1921 1922 # We didn't find it; return None. 1923 return None
    1924
    1925 -def lookup_variable(dotted_name, parent_docs):
    1926 assert isinstance(dotted_name, DottedName) 1927 # If it's a simple identifier, use lookup_name. 1928 if len(dotted_name) == 1: 1929 return lookup_name(dotted_name[0], parent_docs) 1930 1931 # If it's a dotted name with multiple pieces, look up the 1932 # namespace containing the var (=parent) first; and then 1933 # look for the var in that namespace. 1934 else: 1935 parent = lookup_value(dotted_name[:-1], parent_docs) 1936 if (isinstance(parent, NamespaceDoc) and 1937 dotted_name[-1] in parent.variables): 1938 return parent.variables[dotted_name[-1]] 1939 else: 1940 return None # var not found.
    1941
    1942 -def lookup_value(dotted_name, parent_docs):
    1943 """ 1944 Find and return the documentation for the value contained in 1945 the variable with the given name in the current namespace. 1946 """ 1947 assert isinstance(dotted_name, DottedName) 1948 var_doc = lookup_name(dotted_name[0], parent_docs) 1949 1950 for i in range(1, len(dotted_name)): 1951 if var_doc is None: return None 1952 1953 if isinstance(var_doc.value, NamespaceDoc): 1954 var_dict = var_doc.value.variables 1955 elif (var_doc.value is UNKNOWN and 1956 var_doc.imported_from not in (None, UNKNOWN)): 1957 src_name = var_doc.imported_from + dotted_name[i:] 1958 # [xx] do I want to create a proxy here?? 1959 return GenericValueDoc(proxy_for=src_name, 1960 parse_repr=str(dotted_name), 1961 docs_extracted_by='parser') 1962 else: 1963 return None 1964 1965 var_doc = var_dict.get(dotted_name[i]) 1966 1967 if var_doc is None: return None 1968 return var_doc.value
    1969 1970 #///////////////////////////////////////////////////////////////// 1971 #{ Docstring Comments 1972 #///////////////////////////////////////////////////////////////// 1973
    1974 -def add_docstring_from_comments(api_doc, comments):
    1975 if api_doc is None or not comments: return 1976 api_doc.docstring = '\n'.join([line for (line, lineno) in comments]) 1977 api_doc.docstring_lineno = comments[0][1]
    1978 1979 #///////////////////////////////////////////////////////////////// 1980 #{ Tree tokens 1981 #///////////////////////////////////////////////////////////////// 1982
    1983 -def _join_toktree(s1, s2):
    1984 # Join them. s1 = left side; s2 = right side. 1985 if (s2=='' or s1=='' or 1986 s1 in ('-','`') or s2 in ('}',']',')','`',':') or 1987 s2[0] in ('.',',') or s1[-1] in ('(','[','{','.','\n',' ') or 1988 (s2[0] == '(' and s1[-1] not in (',','='))): 1989 return '%s%s' % (s1,s2) 1990 elif (spacing=='tight' and 1991 s1[-1] in '+-*/=,' or s2[0] in '+-*/=,'): 1992 return '%s%s' % (s1, s2) 1993 else: 1994 return '%s %s' % (s1, s2)
    1995
    1996 -def _pp_toktree_add_piece(spacing, pieces, piece):
    1997 s1 = pieces[-1] 1998 s2 = piece 1999 2000 if (s2=='' or s1=='' or 2001 s1 in ('-','`') or s2 in ('}',']',')','`',':') or 2002 s2[0] in ('.',',') or s1[-1] in ('(','[','{','.','\n',' ') or 2003 (s2[0] == '(' and s1[-1] not in (',','='))): 2004 pass 2005 elif (spacing=='tight' and 2006 s1[-1] in '+-*/=,' or s2[0] in '+-*/=,'): 2007 pass 2008 else: 2009 pieces.append(' ') 2010 2011 pieces.append(piece)
    2012
    2013 -def pp_toktree(elts, spacing='normal', indent=0):
    2014 pieces = [''] 2015 _pp_toktree(elts, spacing, indent, pieces) 2016 return ''.join(pieces)
    2017
    2018 -def _pp_toktree(elts, spacing, indent, pieces):
    2019 add_piece = _pp_toktree_add_piece 2020 2021 for elt in elts: 2022 # Put a blank line before class & def statements. 2023 if elt == (token.NAME, 'class') or elt == (token.NAME, 'def'): 2024 add_piece(spacing, pieces, '\n%s' % (' '*indent)) 2025 2026 if isinstance(elt, tuple): 2027 if elt[0] == token.NEWLINE: 2028 add_piece(spacing, pieces, ' '+elt[1]) 2029 add_piece(spacing, pieces, '\n%s' % (' '*indent)) 2030 elif elt[0] == token.INDENT: 2031 add_piece(spacing, pieces, ' ') 2032 indent += 1 2033 elif elt[0] == token.DEDENT: 2034 assert pieces[-1] == ' ' 2035 pieces.pop() 2036 indent -= 1 2037 elif elt[0] == tokenize.COMMENT: 2038 add_piece(spacing, pieces, elt[1].rstrip() + '\n') 2039 add_piece(' '*indent) 2040 else: 2041 add_piece(spacing, pieces, elt[1]) 2042 else: 2043 _pp_toktree(elt, spacing, indent, pieces)
    2044 2045 #///////////////////////////////////////////////////////////////// 2046 #{ Helper Functions 2047 #///////////////////////////////////////////////////////////////// 2048
    2049 -def get_module_encoding(filename):
    2050 """ 2051 @see: U{PEP 263<http://www.python.org/peps/pep-0263.html>} 2052 """ 2053 module_file = open(filename, 'rU') 2054 try: 2055 lines = [module_file.readline() for i in range(2)] 2056 if lines[0].startswith('\xef\xbb\xbf'): 2057 return 'utf-8' 2058 else: 2059 for line in lines: 2060 m = re.search("coding[:=]\s*([-\w.]+)", line) 2061 if m: return m.group(1) 2062 2063 # Fall back on Python's default encoding. 2064 return 'iso-8859-1' # aka 'latin-1' 2065 finally: 2066 module_file.close()
    2067
    2068 -def _get_module_name(filename, package_doc):
    2069 """ 2070 Return (dotted_name, is_package) 2071 """ 2072 name = re.sub(r'.py\w?$', '', os.path.split(filename)[1]) 2073 if name == '__init__': 2074 is_package = True 2075 name = os.path.split(os.path.split(filename)[0])[1] 2076 else: 2077 is_package = False 2078 2079 # [XX] if the module contains a script, then `name` may not 2080 # necessarily be a valid identifier -- which will cause 2081 # DottedName to raise an exception. Is that what I want? 2082 if package_doc is None: 2083 dotted_name = DottedName(name) 2084 else: 2085 dotted_name = DottedName(package_doc.canonical_name, name) 2086 2087 # Check if the module looks like it's shadowed by a variable. 2088 # If so, then add a "'" to the end of its canonical name, to 2089 # distinguish it from the variable. 2090 if package_doc is not None and name in package_doc.variables: 2091 vardoc = package_doc.variables[name] 2092 if (vardoc.value not in (None, UNKNOWN) and 2093 vardoc.imported_from != dotted_name): 2094 log.warning("Module %s might be shadowed by a variable with " 2095 "the same name." % dotted_name) 2096 dotted_name = DottedName(str(dotted_name)+"'") 2097 2098 return dotted_name, is_package
    2099
    2100 -def flatten(lst, out=None):
    2101 """ 2102 @return: a flat list containing the leaves of the given nested 2103 list. 2104 @param lst: The nested list that should be flattened. 2105 """ 2106 if out is None: out = [] 2107 for elt in lst: 2108 if isinstance(elt, (list, tuple)): 2109 flatten(elt, out) 2110 else: 2111 out.append(elt) 2112 return out
    2113

    epydoc-3.0.1+dfsg/doc/api/toc.html0000644000175000017500000001574210750103050017166 0ustar pronovicpronovic Table of Contents

    Table of Contents


    Everything

    Modules

    epydoc
    epydoc.apidoc
    epydoc.checker
    epydoc.cli
    epydoc.compat
    epydoc.docbuilder
    epydoc.docintrospecter
    epydoc.docparser
    epydoc.docstringparser
    epydoc.docwriter
    epydoc.docwriter.dotgraph
    epydoc.docwriter.html
    epydoc.docwriter.html_colorize
    epydoc.docwriter.html_css
    epydoc.docwriter.html_help
    epydoc.docwriter.latex
    epydoc.docwriter.plaintext
    epydoc.docwriter.xlink
    epydoc.gui
    epydoc.log
    epydoc.markup
    epydoc.markup.doctest
    epydoc.markup.epytext
    epydoc.markup.javadoc
    epydoc.markup.plaintext
    epydoc.markup.pyval_repr
    epydoc.markup.restructuredtext
    epydoc.test
    epydoc.test.util
    epydoc.util

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.NamespaceDoc-class.html0000644000175000017500000017623110750103050024547 0ustar pronovicpronovic epydoc.apidoc.NamespaceDoc
    Package epydoc :: Module apidoc :: Class NamespaceDoc
    [hide private]
    [frames] | no frames]

    Class NamespaceDoc

    source code


    API documentation information about a singe Python namespace value. (I.e., a module or a class).

    Instance Methods [hide private]
     
    __init__(self, **kwargs)
    Construct a new APIDoc object.
    source code
    call graph 
    bool
    is_detailed(self)
    Does this object deserve a box with extra details?
    source code
    call graph 
     
    apidoc_links(self, **filters)
    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
    source code
    call graph 
     
    init_sorted_variables(self)
    Initialize the sorted_variables attribute, based on the variables and sort_spec attributes.
    source code
    call graph 
     
    init_variable_groups(self)
    Initialize the variable_groups attribute, based on the sorted_variables and group_specs attributes.
    source code
    call graph 
     
    group_names(self)
    Return a list of the group names defined by this namespace, in the order in which they should be listed, with no duplicates.
    source code
    call graph 
     
    _init_grouping(self, elts)
    Divide a given a list of APIDoc objects into groups, as specified by self.group_specs.
    source code
    call graph 
     
    report_unused_groups(self)
    Issue a warning for any @group items that were not used by _init_grouping().
    source code
    call graph 

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__

    Inherited from APIDoc: __cmp__, __hash__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from ValueDoc: canonical_name, toktree

        Information about Variables
    dict from string to VariableDoc variables = _Sentinel('UNKNOWN')
    The contents of the namespace, encoded as a dictionary mapping from identifiers to VariableDocs.
    list of VariableDoc sorted_variables = _Sentinel('UNKNOWN')
    A list of all variables defined by this namespace, in sorted order.
    list of str sort_spec = _Sentinel('UNKNOWN')
    The order in which variables should be listed, encoded as a list of names.
    list of (str,list) group_specs = _Sentinel('UNKNOWN')
    The groups that are defined by this namespace's docstrings.
    dict from str to list of VariableDoc variable_groups = _Sentinel('UNKNOWN')
    A dictionary specifying what group each variable belongs to.
        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Information Extracted from Docstrings

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    __init__(self, **kwargs)
    (Constructor)

    source code 
    call graph 

    Construct a new APIDoc object. Keyword arguments may be used to initialize the new APIDoc's attributes.

    Raises:
    • TypeError - If a keyword argument is specified that does not correspond to a valid attribute for this (sub)class of APIDoc.
    Overrides: object.__init__
    (inherited documentation)

    is_detailed(self)

    source code 
    call graph 

    Does this object deserve a box with extra details?

    Returns: bool
    True if the object needs extra details, else False.
    Overrides: APIDoc.is_detailed
    (inherited documentation)

    apidoc_links(self, **filters)

    source code 
    call graph 

    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

    Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

    • imports: Imported variables.
    • packages: Containing packages for modules.
    • submodules: Contained submodules for packages.
    • bases: Bases for classes.
    • subclasses: Subclasses for classes.
    • variables: All variables.
    • private: Private variables.
    • overrides: Points from class variables to the variables they override. This filter is False by default.
    Overrides: APIDoc.apidoc_links
    (inherited documentation)

    init_sorted_variables(self)

    source code 
    call graph 

    Initialize the sorted_variables attribute, based on the variables and sort_spec attributes. This should usually be called after all variables have been added to variables (including any inherited variables for classes).

    _init_grouping(self, elts)

    source code 
    call graph 

    Divide a given a list of APIDoc objects into groups, as specified by self.group_specs.

    Parameters:
    • elts - A list of tuples (name, apidoc).
    Returns:
    A list of tuples (groupname, elts), where groupname is the name of a group and elts is a list of APIDocs in that group. The first tuple has name '', and is used for ungrouped elements. The remaining tuples are listed in the order that they appear in self.group_specs. Within each tuple, the elements are listed in the order that they appear in api_docs.

    Instance Variable Details [hide private]

    variables

    The contents of the namespace, encoded as a dictionary mapping from identifiers to VariableDocs. This dictionary contains all names defined by the namespace, including imported variables, aliased variables, and variables inherited from base classes (once inherit_docs() has added them).
    Type:
    dict from string to VariableDoc
    Value:
    _Sentinel('UNKNOWN')
    

    sorted_variables

    A list of all variables defined by this namespace, in sorted order. The elements of this list should exactly match the values of variables. The sort order for this list is defined as follows:
    • Any variables listed in a @sort docstring field are listed in the order given by that field.
    • These are followed by any variables that were found while parsing the source code, in the order in which they were defined in the source file.
    • Finally, any remaining variables are listed in alphabetical order.
    Type:
    list of VariableDoc
    Value:
    _Sentinel('UNKNOWN')
    

    sort_spec

    The order in which variables should be listed, encoded as a list of names. Any variables whose names are not included in this list should be listed alphabetically, following the variables that are included.
    Type:
    list of str
    Value:
    _Sentinel('UNKNOWN')
    

    group_specs

    The groups that are defined by this namespace's docstrings. group_specs is encoded as an ordered list of tuples (group_name, elt_names), where group_name is the

    name of a group and elt_names is a list of element names in that group. (An element can be a variable or a submodule.) A '*' in an element name will match any string of characters.

    Type:
    list of (str,list)
    Value:
    _Sentinel('UNKNOWN')
    

    variable_groups

    A dictionary specifying what group each variable belongs to. The keys of the dictionary are group names, and the values are lists of VariableDocs. The order that groups should be listed in should be taken from group_specs.
    Type:
    dict from str to list of VariableDoc
    Value:
    _Sentinel('UNKNOWN')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.ValueDoc-class.html0000644000175000017500000016221510750103050023724 0ustar pronovicpronovic epydoc.apidoc.ValueDoc
    Package epydoc :: Module apidoc :: Class ValueDoc
    [hide private]
    [frames] | no frames]

    Class ValueDoc

    source code


    API documentation information about a single Python value.

    Instance Methods [hide private]
     
    __repr__(self)
    repr(x)
    source code
    call graph 
     
    __setstate__(self, state) source code
     
    __getstate__(self)
    State serializer for the pickle module.
    source code
     
    apidoc_links(self, **filters)
    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
    source code
    call graph 

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, is_detailed, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation
    ColorizedPyvalRepr
    pyval_repr(self)
    Return a formatted representation of the Python object described by this ValueDoc.
    source code
    call graph 
    ColorizedPyvalRepr
    summary_pyval_repr(self, max_len=None)
    Return a single-line formatted representation of the Python object described by this ValueDoc.
    source code
    call graph 
    Class Variables [hide private]
        Value Representation
      REPR_MAXLINES = 5
    The maximum number of lines of text that should be generated by pyval_repr().
      REPR_LINELEN = 75
    The maximum number of characters for lines of text that should be generated by pyval_repr().
      SUMMARY_REPR_LINELEN = 75
    The maximum number of characters for the single-line text representation generated by summary_pyval_repr().
      REPR_MIN_SCORE = 0
    The minimum score that a value representation based on pyval should have in order to be used instead of parse_repr as the canonical representation for this ValueDoc's value.
    Instance Variables [hide private]
    DottedName canonical_name = _Sentinel('UNKNOWN')
    A dotted name that serves as a unique identifier for this ValueDoc's value.
      toktree = _Sentinel('UNKNOWN')
    This is currently used to extract values from __all__, etc, in the docparser module; maybe I should specialize process_assignment and extract it there? Although, for __all__, it's not clear where I'd put the value, since I just use it to set private/public/imported attribs on other vars (that might not exist yet at the time.)
        Value Representation
    Python object pyval = _Sentinel('UNKNOWN')
    A pointer to the actual Python object described by this ValueDoc.
    unicode parse_repr = _Sentinel('UNKNOWN')
    A text representation of this value, extracted from parsing its source code.
        Context
    ModuleDoc defining_module = _Sentinel('UNKNOWN')
    The documentation for the module that defines this value.
        Information about Imported Variables
    DottedName proxy_for = None
    If proxy_for is not None, then this value was imported from another file.
        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Information Extracted from Docstrings

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    __repr__(self)
    (Representation operator)

    source code 
    call graph 
    repr(x)
    
    
    Overrides: object.__repr__
    (inherited documentation)

    __getstate__(self)

    source code 

    State serializer for the pickle module. This is necessary because sometimes the pyval attribute contains an un-pickleable value.

    pyval_repr(self)

    source code 
    call graph 

    Return a formatted representation of the Python object described by this ValueDoc. This representation may include data from introspection or parsing, and is authorative as 'the best way to represent a Python value.' Any lines that go beyond REPR_LINELEN characters will be wrapped; and if the representation as a whole takes more than REPR_MAXLINES lines, then it will be truncated (with an ellipsis marker). This function will never return UNKNOWN or None.

    Returns: ColorizedPyvalRepr

    summary_pyval_repr(self, max_len=None)

    source code 
    call graph 

    Return a single-line formatted representation of the Python object described by this ValueDoc. This representation may include data from introspection or parsing, and is authorative as 'the best way to summarize a Python value.' If the representation takes more then SUMMARY_REPR_LINELEN characters, then it will be truncated (with an ellipsis marker). This function will never return UNKNOWN or None.

    Returns: ColorizedPyvalRepr

    apidoc_links(self, **filters)

    source code 
    call graph 

    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

    Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

    • imports: Imported variables.
    • packages: Containing packages for modules.
    • submodules: Contained submodules for packages.
    • bases: Bases for classes.
    • subclasses: Subclasses for classes.
    • variables: All variables.
    • private: Private variables.
    • overrides: Points from class variables to the variables they override. This filter is False by default.
    Overrides: APIDoc.apidoc_links
    (inherited documentation)

    Class Variable Details [hide private]

    REPR_MAXLINES

    The maximum number of lines of text that should be generated by pyval_repr(). If the string representation does not fit in this number of lines, an ellpsis marker (...) will be placed at the end of the formatted representation.
    Value:
    5
    

    REPR_LINELEN

    The maximum number of characters for lines of text that should be generated by pyval_repr(). Any lines that exceed this number of characters will be line-wrappped; The \ symbol will be used to indicate that the line was wrapped.
    Value:
    75
    

    SUMMARY_REPR_LINELEN

    The maximum number of characters for the single-line text representation generated by summary_pyval_repr(). If the value's representation does not fit in this number of characters, an ellipsis marker (...) will be placed at the end of the formatted representation.
    Value:
    75
    

    REPR_MIN_SCORE

    The minimum score that a value representation based on pyval should have in order to be used instead of parse_repr as the canonical representation for this ValueDoc's value.
    Value:
    0
    

    Instance Variable Details [hide private]

    canonical_name

    A dotted name that serves as a unique identifier for this ValueDoc's value. If the value can be reached using a single sequence of identifiers (given the appropriate imports), then that sequence of identifiers is used as its canonical name. If the value can be reached by multiple sequences of identifiers (i.e., if it has multiple aliases), then one of those sequences of identifiers is used. If the value cannot be reached by any sequence of identifiers (e.g., if it was used as a base class but then its variable was deleted), then its canonical name will start with '??'. If necessary, a dash followed by a number will be appended to the end of a non-reachable identifier to make its canonical name unique.

    When possible, canonical names are chosen when new ValueDocs are created. However, this is sometimes not possible. If a canonical name can not be chosen when the ValueDoc is created, then one will be assigned by assign_canonical_names().

    Type:
    DottedName
    Value:
    _Sentinel('UNKNOWN')
    

    pyval

    A pointer to the actual Python object described by this ValueDoc. This is used to display the value (e.g., when describing a variable.) Use pyval_repr() to generate a plaintext string representation of this value.
    Type:
    Python object
    Value:
    _Sentinel('UNKNOWN')
    

    parse_repr

    A text representation of this value, extracted from parsing its source code. This representation may not accurately reflect the actual value (e.g., if the value was modified after the initial assignment).
    Type:
    unicode
    Value:
    _Sentinel('UNKNOWN')
    

    defining_module

    The documentation for the module that defines this value. This is used, e.g., to lookup the appropriate markup language for docstrings. For a ModuleDoc, defining_module should be self.
    Type:
    ModuleDoc
    Value:
    _Sentinel('UNKNOWN')
    

    proxy_for

    If proxy_for is not None, then this value was imported from another file. proxy_for is the dotted name of the variable that this value was imported from. If that variable is documented, then its value may contain more complete API documentation about this value. The proxy_for attribute is used by the source code parser to link imported values to their source values (in particular, for base classes). When possible, these proxy ValueDocs are replaced by the imported value's ValueDoc by link_imports().
    Type:
    DottedName
    Value:
    None
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.test-pysrc.html0000644000175000017500000007654710750103050022012 0ustar pronovicpronovic epydoc.test
    Package epydoc :: Package test
    [hide private]
    [frames] | no frames]

    Source Code for Package epydoc.test

     1  # epydoc -- Regression testing 
     2  # 
     3  # Copyright (C) 2005 Edward Loper 
     4  # Author: Edward Loper <edloper@loper.org> 
     5  # URL: <http://epydoc.sf.net> 
     6  # 
     7  # $Id: __init__.py 1502 2007-02-14 08:38:44Z edloper $ 
     8   
     9  """ 
    10  Regression testing. 
    11  """ 
    12  __docformat__ = 'epytext en' 
    13   
    14  import unittest, doctest, epydoc, os, os.path, re, sys 
    15   
    
    16 -def main():
    17 try: 18 doctest.register_optionflag 19 except: 20 print ("\n" 21 "The regression test suite requires a more recent version of\n" 22 "doctest (e.g., the version that ships with Python 2.4 or 2.5).\n" 23 "Please place a new version of doctest on your path before \n" 24 "running the test suite.\n") 25 return 26 27 28 PY24 = doctest.register_optionflag('PYTHON2.4') 29 """Flag indicating that a doctest example requires Python 2.4+""" 30 31 PY25 = doctest.register_optionflag('PYTHON2.5') 32 """Flag indicating that a doctest example requires Python 2.5+""" 33 34 class DocTestParser(doctest.DocTestParser): 35 """ 36 Custom doctest parser that adds support for two new flags 37 +PYTHON2.4 and +PYTHON2.5. 38 """ 39 def parse(self, string, name='<string>'): 40 pieces = doctest.DocTestParser.parse(self, string, name) 41 for i, val in enumerate(pieces): 42 if (isinstance(val, doctest.Example) and 43 ((val.options.get(PY24, False) and 44 sys.version[:2] < (2,4)) or 45 (val.options.get(PY25, False) and 46 sys.version[:2] < (2,5)))): 47 pieces[i] = doctest.Example('1', '1') 48 return pieces
    49 50 # Turn on debugging. 51 epydoc.DEBUG = True 52 53 # Options for doctest: 54 options = doctest.ELLIPSIS 55 doctest.set_unittest_reportflags(doctest.REPORT_UDIFF) 56 57 # Use a custom parser 58 parser = DocTestParser() 59 60 # Find all test cases. 61 tests = [] 62 testdir = os.path.join(os.path.split(__file__)[0]) 63 if testdir == '': testdir = '.' 64 for filename in os.listdir(testdir): 65 if (filename.endswith('.doctest') and 66 check_requirements(os.path.join(testdir, filename))): 67 tests.append(doctest.DocFileSuite(filename, optionflags=options, 68 parser=parser)) 69 70 # Run all test cases. 71 unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(tests))

    72
    73 -def check_requirements(filename):
    74 """ 75 Search for strings of the form:: 76 77 [Require: <module>] 78 79 If any are found, then try importing the module named <module>. 80 If the import fails, then return False. If all required modules 81 are found, return True. (This includes the case where no 82 requirements are listed.) 83 """ 84 s = open(filename).read() 85 for m in re.finditer('(?mi)^[ ]*\:RequireModule:(.*)$', s): 86 module = m.group(1).strip() 87 try: 88 __import__(module) 89 except ImportError: 90 print ('Skipping %r (required module %r not found)' % 91 (os.path.split(filename)[-1], module)) 92 return False 93 return True
    94 95 96 if __name__=='__main__': 97 main() 98
    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext-module.html0000644000175000017500000036511310750103050024146 0ustar pronovicpronovic epydoc.markup.epytext
    Package epydoc :: Package markup :: Module epytext
    [hide private]
    [frames] | no frames]

    Module epytext

    source code

    Parser for epytext strings. Epytext is a lightweight markup whose primary intended application is Python documentation strings. This parser converts Epytext strings to a simple DOM-like representation (encoded as a tree of Element objects and strings). Epytext strings can contain the following structural blocks:

    • epytext: The top-level element of the DOM tree.
    • para: A paragraph of text. Paragraphs contain no newlines, and all spaces are soft.
    • section: A section or subsection.
    • field: A tagged field. These fields provide information about specific aspects of a Python object, such as the description of a function's parameter, or the author of a module.
    • literalblock: A block of literal text. This text should be displayed as it would be displayed in plaintext. The parser removes the appropriate amount of leading whitespace from each line in the literal block.
    • doctestblock: A block containing sample python code, formatted according to the specifications of the doctest module.
    • ulist: An unordered list.
    • olist: An ordered list.
    • li: A list item. This tag is used both for unordered list items and for ordered list items.

    Additionally, the following inline regions may be used within para blocks:

    • code: Source code and identifiers.
    • math: Mathematical expressions.
    • index: A term which should be included in an index, if one is generated.
    • italic: Italicized text.
    • bold: Bold-faced text.
    • uri: A Universal Resource Indicator (URI) or Universal Resource Locator (URL)
    • link: A Python identifier which should be hyperlinked to the named object's documentation, when possible.

    The returned DOM tree will conform to the the following Document Type Description:

      <!ENTITY % colorized '(code | math | index | italic |
                             bold | uri | link | symbol)*'>
    
      <!ELEMENT epytext ((para | literalblock | doctestblock |
                         section | ulist | olist)*, fieldlist?)>
    
      <!ELEMENT para (#PCDATA | %colorized;)*>
    
      <!ELEMENT section (para | listblock | doctestblock |
                         section | ulist | olist)+>
    
      <!ELEMENT fieldlist (field+)>
      <!ELEMENT field (tag, arg?, (para | listblock | doctestblock)
                                   ulist | olist)+)>
      <!ELEMENT tag (#PCDATA)>
      <!ELEMENT arg (#PCDATA)>
      
      <!ELEMENT literalblock (#PCDATA | %colorized;)*>
      <!ELEMENT doctestblock (#PCDATA)>
    
      <!ELEMENT ulist (li+)>
      <!ELEMENT olist (li+)>
      <!ELEMENT li (para | literalblock | doctestblock | ulist | olist)+>
      <!ATTLIST li bullet NMTOKEN #IMPLIED>
      <!ATTLIST olist start NMTOKEN #IMPLIED>
    
      <!ELEMENT uri     (name, target)>
      <!ELEMENT link    (name, target)>
      <!ELEMENT name    (#PCDATA | %colorized;)*>
      <!ELEMENT target  (#PCDATA)>
      
      <!ELEMENT code    (#PCDATA | %colorized;)*>
      <!ELEMENT math    (#PCDATA | %colorized;)*>
      <!ELEMENT italic  (#PCDATA | %colorized;)*>
      <!ELEMENT bold    (#PCDATA | %colorized;)*>
      <!ELEMENT indexed (#PCDATA | %colorized;)>
      <!ATTLIST code style CDATA #IMPLIED>
    
      <!ELEMENT symbol (#PCDATA)>
    
    Classes [hide private]
      Element
    A very simple DOM-like representation for parsed epytext documents.
      Token
    Tokens are an intermediate data structure used while constructing the structuring DOM tree for a formatted docstring.
      TokenizationError
    An error generated while tokenizing a formatted documentation string.
      StructuringError
    An error generated while structuring a formatted documentation string.
      ColorizingError
    An error generated while colorizing a paragraph.
      ParsedEpytextDocstring
    Functions [hide private]
    Element
    parse(str, errors=None)
    Return a DOM tree encoding the contents of an epytext string.
    source code
    call graph 
     
    _raise_graphs(tree, parent) source code
    call graph 
     
    _pop_completed_blocks(token, stack, indent_stack)
    Pop any completed blocks off the stack.
    source code
    call graph 
     
    _add_para(doc, para_token, stack, indent_stack, errors)
    Colorize the given paragraph, and add it to the DOM tree.
    source code
    call graph 
     
    _add_section(doc, heading_token, stack, indent_stack, errors)
    Add a new section to the DOM tree, with the given heading.
    source code
    call graph 
     
    _add_list(doc, bullet_token, stack, indent_stack, errors)
    Add a new list item or field to the DOM tree, with the given bullet or field tag.
    source code
    call graph 
    int
    _tokenize_doctest(lines, start, block_indent, tokens, errors)
    Construct a Token containing the doctest block starting at lines[start], and append it to tokens.
    source code
    call graph 
    int
    _tokenize_literal(lines, start, block_indent, tokens, errors)
    Construct a Token containing the literal block starting at lines[start], and append it to tokens.
    source code
    call graph 
    int
    _tokenize_listart(lines, start, bullet_indent, tokens, errors)
    Construct Tokens for the bullet and the first paragraph of the list item (or field) starting at lines[start], and append them to tokens.
    source code
    call graph 
    int
    _tokenize_para(lines, start, para_indent, tokens, errors)
    Construct a Token containing the paragraph starting at lines[start], and append it to tokens.
    source code
    call graph 
    list of Token
    _tokenize(str, errors)
    Split a given formatted docstring into an ordered list of Tokens, according to the epytext markup rules.
    source code
    call graph 
    Element
    _colorize(doc, token, errors, tagName='para')
    Given a string containing the contents of a paragraph, produce a DOM Element encoding that paragraph.
    source code
    call graph 
     
    _colorize_graph(doc, graph, token, end, errors)
    Eg:
    source code
    call graph 
     
    _colorize_link(doc, link, token, end, errors) source code
    call graph 
    string
    to_epytext(tree, indent=0, seclevel=0)
    Convert a DOM document encoding epytext back to an epytext string.
    source code
    string
    to_plaintext(tree, indent=0, seclevel=0)
    Convert a DOM document encoding epytext to a string representation.
    source code
    call graph 
    string
    to_debug(tree, indent=4, seclevel=0)
    Convert a DOM document encoding epytext back to an epytext string, annotated with extra debugging information.
    source code
    Element
    pparse(str, show_warnings=1, show_errors=1, stream=sys.stderr)
    Pretty-parse the string.
    source code
    Element
    parse_as_literal(str)
    Return a DOM document matching the epytext DTD, containing a single literal block.
    source code
    Element
    parse_as_para(str)
    Return a DOM document matching the epytext DTD, containing a single paragraph.
    source code
    call graph 
    ParsedDocstring
    parse_docstring(docstring, errors, **options)
    Parse the given docstring, which is formatted using epytext; and return a ParsedDocstring representation of its contents.
    source code
    call graph 
    Variables [hide private]
      _HEADING_CHARS = '=-~'
      _ESCAPES = {'lb': '{', 'rb': '}'}
      SYMBOLS = ['<-', '->', '^', 'v', 'alpha', 'beta', 'gamma', 'de...
    A list of the of escape symbols that are supported by epydoc.
      _SYMBOLS = {'->': 1, '<-': 1, '<=': 1, '>=': 1, 'Alpha': 1, 'B...
      __doc__ = __doc__.replace('<<<SYMBOLS>>>', symblist)
      _COLORIZING_TAGS = {'B': 'bold', 'C': 'code', 'E': 'escape', '...
      _LINK_COLORIZING_TAGS = ['link', 'uri']
      _BULLET_RE = re.compile(r'-( +|$)|(\d+\.)+( +|$)|@\w+( [^\{\}:...
      _LIST_BULLET_RE = re.compile(r'-( +|$)|(\d+\.)+( +|$)')
      _FIELD_BULLET_RE = re.compile(r'@\w+( [^\{\}:\n]+)?:')
      _BRACE_RE = re.compile(r'[\{\}]')
      _TARGET_RE = re.compile(r'^(.*?)\s*<(?:URI:|L:)?([^<>]+)>$')
      GRAPH_TYPES = ['classtree', 'packagetree', 'importgraph', 'cal...
      SYMBOL_TO_PLAINTEXT = {'crarr': '\\'}
    Function Details [hide private]

    parse(str, errors=None)

    source code 
    call graph 

    Return a DOM tree encoding the contents of an epytext string. Any errors generated during parsing will be stored in errors.

    Parameters:
    • str (string) - The epytext string to parse.
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored. If no list is specified, then fatal errors will generate exceptions, and non-fatal errors will be ignored.
    Returns: Element
    a DOM tree encoding the contents of an epytext string.
    Raises:
    • ParseError - If errors is None and an error is encountered while parsing.

    _pop_completed_blocks(token, stack, indent_stack)

    source code 
    call graph 

    Pop any completed blocks off the stack. This includes any blocks that we have dedented past, as well as any list item blocks that we've dedented to. The top element on the stack should only be a list if we're about to start a new list item (i.e., if the next token is a bullet).

    _add_list(doc, bullet_token, stack, indent_stack, errors)

    source code 
    call graph 

    Add a new list item or field to the DOM tree, with the given bullet or field tag. When necessary, create the associated list.

    _tokenize_doctest(lines, start, block_indent, tokens, errors)

    source code 
    call graph 

    Construct a Token containing the doctest block starting at lines[start], and append it to tokens. block_indent should be the indentation of the doctest block. Any errors generated while tokenizing the doctest block will be appended to errors.

    Parameters:
    • lines (list of string) - The list of lines to be tokenized
    • start (int) - The index into lines of the first line of the doctest block to be tokenized.
    • block_indent (int) - The indentation of lines[start]. This is the indentation of the doctest block.
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored. If no list is specified, then errors will generate exceptions.
    • tokens (list of Token)
    Returns: int
    The line number of the first line following the doctest block.

    _tokenize_literal(lines, start, block_indent, tokens, errors)

    source code 
    call graph 

    Construct a Token containing the literal block starting at lines[start], and append it to tokens. block_indent should be the indentation of the literal block. Any errors generated while tokenizing the literal block will be appended to errors.

    Parameters:
    • lines (list of string) - The list of lines to be tokenized
    • start (int) - The index into lines of the first line of the literal block to be tokenized.
    • block_indent (int) - The indentation of lines[start]. This is the indentation of the literal block.
    • errors (list of ParseError) - A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list.
    • tokens (list of Token)
    Returns: int
    The line number of the first line following the literal block.

    _tokenize_listart(lines, start, bullet_indent, tokens, errors)

    source code 
    call graph 

    Construct Tokens for the bullet and the first paragraph of the list item (or field) starting at lines[start], and append them to tokens. bullet_indent should be the indentation of the list item. Any errors generated while tokenizing will be appended to errors.

    Parameters:
    • lines (list of string) - The list of lines to be tokenized
    • start (int) - The index into lines of the first line of the list item to be tokenized.
    • bullet_indent (int) - The indentation of lines[start]. This is the indentation of the list item.
    • errors (list of ParseError) - A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list.
    • tokens (list of Token)
    Returns: int
    The line number of the first line following the list item's first paragraph.

    _tokenize_para(lines, start, para_indent, tokens, errors)

    source code 
    call graph 

    Construct a Token containing the paragraph starting at lines[start], and append it to tokens. para_indent should be the indentation of the paragraph . Any errors generated while tokenizing the paragraph will be appended to errors.

    Parameters:
    • lines (list of string) - The list of lines to be tokenized
    • start (int) - The index into lines of the first line of the paragraph to be tokenized.
    • para_indent (int) - The indentation of lines[start]. This is the indentation of the paragraph.
    • errors (list of ParseError) - A list of the errors generated by parsing. Any new errors generated while will tokenizing this paragraph will be appended to this list.
    • tokens (list of Token)
    Returns: int
    The line number of the first line following the paragraph.

    _tokenize(str, errors)

    source code 
    call graph 

    Split a given formatted docstring into an ordered list of Tokens, according to the epytext markup rules.

    Parameters:
    • str (string) - The epytext string
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored. If no list is specified, then errors will generate exceptions.
    Returns: list of Token
    a list of the Tokens that make up the given string.

    _colorize(doc, token, errors, tagName='para')

    source code 
    call graph 

    Given a string containing the contents of a paragraph, produce a DOM Element encoding that paragraph. Colorized regions are represented using DOM Elements, and text is represented using DOM Texts.

    Parameters:
    • errors (list of string) - A list of errors. Any newly generated errors will be appended to this list.
    • tagName (string) - The element tag for the DOM Element that should be generated.
    Returns: Element
    a DOM Element encoding the given paragraph.

    _colorize_graph(doc, graph, token, end, errors)

    source code 
    call graph 

    Eg:

     G{classtree}
     G{classtree x, y, z}
     G{importgraph}
    

    to_epytext(tree, indent=0, seclevel=0)

    source code 

    Convert a DOM document encoding epytext back to an epytext string. This is the inverse operation from parse. I.e., assuming there are no errors, the following is true:

    • parse(to_epytext(tree)) == tree

    The inverse is true, except that whitespace, line wrapping, and character escaping may be done differently.

    • to_epytext(parse(str)) == str (approximately)
    Parameters:
    • tree (Element) - A DOM document encoding of an epytext string.
    • indent (int) - The indentation for the string representation of tree. Each line of the returned string will begin with indent space characters.
    • seclevel (int) - The section level that tree appears at. This is used to generate section headings.
    Returns: string
    The epytext string corresponding to tree.

    to_plaintext(tree, indent=0, seclevel=0)

    source code 
    call graph 

    Convert a DOM document encoding epytext to a string representation. This representation is similar to the string generated by to_epytext, but to_plaintext removes inline markup, prints escaped characters in unescaped form, etc.

    Parameters:
    • tree (Element) - A DOM document encoding of an epytext string.
    • indent (int) - The indentation for the string representation of tree. Each line of the returned string will begin with indent space characters.
    • seclevel (int) - The section level that tree appears at. This is used to generate section headings.
    Returns: string
    The epytext string corresponding to tree.

    to_debug(tree, indent=4, seclevel=0)

    source code 

    Convert a DOM document encoding epytext back to an epytext string, annotated with extra debugging information. This function is similar to to_epytext, but it adds explicit information about where different blocks begin, along the left margin.

    Parameters:
    • tree (Element) - A DOM document encoding of an epytext string.
    • indent (int) - The indentation for the string representation of tree. Each line of the returned string will begin with indent space characters.
    • seclevel (int) - The section level that tree appears at. This is used to generate section headings.
    Returns: string
    The epytext string corresponding to tree.

    pparse(str, show_warnings=1, show_errors=1, stream=sys.stderr)

    source code 

    Pretty-parse the string. This parses the string, and catches any warnings or errors produced. Any warnings and errors are displayed, and the resulting DOM parse structure is returned.

    Parameters:
    • str (string) - The string to parse.
    • show_warnings (boolean) - Whether or not to display non-fatal errors generated by parsing str.
    • show_errors (boolean) - Whether or not to display fatal errors generated by parsing str.
    • stream (stream) - The stream that warnings and errors should be written to.
    Returns: Element
    a DOM document encoding the contents of str.
    Raises:
    • SyntaxError - If any fatal errors were encountered.

    parse_as_literal(str)

    source code 

    Return a DOM document matching the epytext DTD, containing a single literal block. That literal block will include the contents of the given string. This method is typically used as a fall-back when the parser fails.

    Parameters:
    • str (string) - The string which should be enclosed in a literal block.
    Returns: Element
    A DOM document containing str in a single literal block.

    parse_as_para(str)

    source code 
    call graph 

    Return a DOM document matching the epytext DTD, containing a single paragraph. That paragraph will include the contents of the given string. This can be used to wrap some forms of automatically generated information (such as type names) in paragraphs.

    Parameters:
    • str (string) - The string which should be enclosed in a paragraph.
    Returns: Element
    A DOM document containing str in a single paragraph.

    parse_docstring(docstring, errors, **options)

    source code 
    call graph 

    Parse the given docstring, which is formatted using epytext; and return a ParsedDocstring representation of its contents.

    Parameters:
    • docstring (string) - The docstring to parse
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored.
    • options - Extra options. Unknown options are ignored. Currently, no extra options are defined.
    Returns: ParsedDocstring

    Variables Details [hide private]

    SYMBOLS

    A list of the of escape symbols that are supported by epydoc. Currently the following symbols are supported:
    • S{<-}=←;
    • S{->}=→;
    • S{^}=↑;
    • S{v}=↓;
    • S{alpha}=α;
    • S{beta}=β;
    • S{gamma}=γ;
    • S{delta}=δ;
    • S{epsilon}=ε;
    • S{zeta}=ζ;
    • S{eta}=η;
    • S{theta}=θ;
    • S{iota}=ι;
    • S{kappa}=κ;
    • S{lambda}=λ;
    • S{mu}=μ;
    • S{nu}=ν;
    • S{xi}=ξ;
    • S{omicron}=ο;
    • S{pi}=π;
    • S{rho}=ρ;
    • S{sigma}=σ;
    • S{tau}=τ;
    • S{upsilon}=υ;
    • S{phi}=φ;
    • S{chi}=χ;
    • S{psi}=ψ;
    • S{omega}=ω;
    • S{Alpha}=Α;
    • S{Beta}=Β;
    • S{Gamma}=Γ;
    • S{Delta}=Δ;
    • S{Epsilon}=Ε;
    • S{Zeta}=Ζ;
    • S{Eta}=Η;
    • S{Theta}=Θ;
    • S{Iota}=Ι;
    • S{Kappa}=Κ;
    • S{Lambda}=Λ;
    • S{Mu}=Μ;
    • S{Nu}=Ν;
    • S{Xi}=Ξ;
    • S{Omicron}=Ο;
    • S{Pi}=Π;
    • S{Rho}=Ρ;
    • S{Sigma}=Σ;
    • S{Tau}=Τ;
    • S{Upsilon}=Υ;
    • S{Phi}=Φ;
    • S{Chi}=Χ;
    • S{Psi}=Ψ;
    • S{Omega}=Ω;
    • S{larr}=←;
    • S{rarr}=→;
    • S{uarr}=↑;
    • S{darr}=↓;
    • S{harr}=↔;
    • S{crarr}=\;
    • S{lArr}=⇐;
    • S{rArr}=⇒;
    • S{uArr}=⇑;
    • S{dArr}=⇓;
    • S{hArr}=⇔;
    • S{copy}=©;
    • S{times}=×;
    • S{forall}=∀;
    • S{exist}=∃;
    • S{part}=∂;
    • S{empty}=∅;
    • S{isin}=∈;
    • S{notin}=∉;
    • S{ni}=∋;
    • S{prod}=∏;
    • S{sum}=∑;
    • S{prop}=∝;
    • S{infin}=∞;
    • S{ang}=∠;
    • S{and}=∧;
    • S{or}=∨;
    • S{cap}=∩;
    • S{cup}=∪;
    • S{int}=∫;
    • S{there4}=∴;
    • S{sim}=∼;
    • S{cong}=≅;
    • S{asymp}=≈;
    • S{ne}=≠;
    • S{equiv}=≡;
    • S{le}=≤;
    • S{ge}=≥;
    • S{sub}=⊂;
    • S{sup}=⊃;
    • S{nsub}=⊄;
    • S{sube}=⊆;
    • S{supe}=⊇;
    • S{oplus}=⊕;
    • S{otimes}=⊗;
    • S{perp}=⊥;
    • S{infinity}=∞;
    • S{integral}=∫;
    • S{product}=∏;
    • S{>=}=≥;
    • S{<=}=≤
    Value:
    ['<-',
     '->',
     '^',
     'v',
     'alpha',
     'beta',
     'gamma',
     'delta',
    ...
    

    _SYMBOLS

    Value:
    {'->': 1,
     '<-': 1,
     '<=': 1,
     '>=': 1,
     'Alpha': 1,
     'Beta': 1,
     'Chi': 1,
     'Delta': 1,
    ...
    

    _COLORIZING_TAGS

    Value:
    {'B': 'bold',
     'C': 'code',
     'E': 'escape',
     'G': 'graph',
     'I': 'italic',
     'L': 'link',
     'M': 'math',
     'S': 'symbol',
    ...
    

    _BULLET_RE

    Value:
    re.compile(r'-( +|$)|(\d+\.)+( +|$)|@\w+( [^\{\}:\n]+)?:')
    

    GRAPH_TYPES

    Value:
    ['classtree', 'packagetree', 'importgraph', 'callgraph']
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.gui-module.html0000644000175000017500000016411310750103050021727 0ustar pronovicpronovic epydoc.gui
    Package epydoc :: Module gui
    [hide private]
    [frames] | no frames]

    Module gui

    source code

    Graphical interface to epydoc. This interface might be useful for systems where it's inconvenient to use the command-line interface (such as Windows). It supports many (but not all) of the features that are supported by the command-line interface. It also supports loading and saving of project files, which store a set of related modules, and the options that should be used to generate the documentation for those modules.

    Usage:

       epydocgui [OPTIONS] [FILE.prj | MODULES...]
    
       FILE.prj                  An epydoc GUI project file.
       MODULES...                A list of Python modules to document.
       -V, --version             Print the version of epydoc.
       -h, -?, --help, --usage   Display this usage message
       --debug                   Do not suppress error messages
    

    To Do: Use ini-style project files, rather than pickles (using the same format as the CLI).

    Classes [hide private]
      GUILogger
      EpydocGUI
    A graphical user interace to epydoc.
    Functions [hide private]
     
    document(options, cancel, done)
    Create the documentation for modules, using the options specified by options.
    source code
    None
    _version()
    Display the version information, and exit.
    source code
     
    _usage() source code
     
    _error(s) source code
     
    gui() source code
    Variables [hide private]
      DEBUG = 0
      BG_COLOR = '#e0e0e0'
      ACTIVEBG_COLOR = '#e0e0e0'
      TEXT_COLOR = 'black'
      ENTRYSELECT_COLOR = '#e0e0e0'
      SELECT_COLOR = '#208070'
      MESSAGE_COLOR = '#000060'
      ERROR_COLOR = '#600000'
      GUIERROR_COLOR = '#600000'
      WARNING_COLOR = '#604000'
      HEADER_COLOR = '#000000'
      COLOR_CONFIG = {'background': '#e0e0e0', 'foreground': 'black'...
      ENTRY_CONFIG = {'background': '#e0e0e0', 'foreground': 'black'...
      SB_CONFIG = {'activebackground': '#e0e0e0', 'background': '#e0...
      LISTBOX_CONFIG = {'background': '#e0e0e0', 'foreground': 'blac...
      BUTTON_CONFIG = {'activebackground': '#e0e0e0', 'activeforegro...
      CBUTTON_CONFIG = {'activebackground': '#e0e0e0', 'activeforegr...
      SHOWMSG_CONFIG = {'activebackground': '#e0e0e0', 'activeforegr...
      SHOWWRN_CONFIG = {'activebackground': '#e0e0e0', 'activeforegr...
      SHOWERR_CONFIG = {'activebackground': '#e0e0e0', 'activeforegr...
      PROGRESS_HEIGHT = 16
      PROGRESS_WIDTH = 200
      PROGRESS_BG = '#305060'
      PROGRESS_COLOR1 = '#30c070'
      PROGRESS_COLOR2 = '#60ffa0'
      PROGRESS_COLOR3 = '#106030'
      DX = 1
      DY = 1
      DH = 1
      DW = 3
      IMPORT_PROGRESS = 0.1
      BUILD_PROGRESS = 0.2
      WRITE_PROGRESS = 0.7
      UP_GIF = 'R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAA...
      DOWN_GIF = 'R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////w...
      LEFT_GIF = 'R0lGODlhDAALAKIAANnZ2QDMmQCZZgBmZgAAAAAzM////////y...
      RIGHT_GIF = 'R0lGODlhDAALAKIAANnZ2QDMmQBmZgCZZgAzMwAAAP///////...
    Function Details [hide private]

    document(options, cancel, done)

    source code 

    Create the documentation for modules, using the options specified by options. document is designed to be started in its own thread by EpydocGUI._go.

    Parameters:
    • options (dictionary) - The options to use for generating documentation. This includes keyword options that can be given to docwriter.html.HTMLWriter, as well as the option target, which controls where the output is written to.

    Variables Details [hide private]

    COLOR_CONFIG

    Value:
    {'background': '#e0e0e0',
     'foreground': 'black',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0'}
    

    ENTRY_CONFIG

    Value:
    {'background': '#e0e0e0',
     'foreground': 'black',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'selectbackground': '#e0e0e0',
     'selectforeground': 'black'}
    

    SB_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'background': '#e0e0e0',
     'highlightbackground': '#e0e0e0',
     'troughcolor': '#e0e0e0'}
    

    LISTBOX_CONFIG

    Value:
    {'background': '#e0e0e0',
     'foreground': 'black',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'selectbackground': '#e0e0e0',
     'selectforeground': 'black'}
    

    BUTTON_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'activeforeground': 'black',
     'background': '#e0e0e0',
     'foreground': 'black',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'highlightthickness': 0,
     'padx': 4,
    ...
    

    CBUTTON_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'activeforeground': 'black',
     'background': '#e0e0e0',
     'foreground': 'black',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'highlightthickness': 0,
     'padx': 4,
    ...
    

    SHOWMSG_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'activeforeground': 'black',
     'background': '#e0e0e0',
     'foreground': '#000060',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'highlightthickness': 0,
     'padx': 4,
    ...
    

    SHOWWRN_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'activeforeground': 'black',
     'background': '#e0e0e0',
     'foreground': '#604000',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'highlightthickness': 0,
     'padx': 4,
    ...
    

    SHOWERR_CONFIG

    Value:
    {'activebackground': '#e0e0e0',
     'activeforeground': 'black',
     'background': '#e0e0e0',
     'foreground': '#600000',
     'highlightbackground': '#e0e0e0',
     'highlightcolor': '#e0e0e0',
     'highlightthickness': 0,
     'padx': 4,
    ...
    

    UP_GIF

    Value:
    '''R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAA\
    AAAAAAAAA
    AAAAACH5BAEAAAAALAAAAAALAAwAAAQjEMhJKxCW4gzCIJxXZIEwFGDlDadqsii1sq1U0n\
    A64+ON
    5xEAOw==
    '''
    

    DOWN_GIF

    Value:
    '''R0lGODlhCwAMALMAANnZ2QDMmQCZZgBmZgAAAAAzM////////wAAAAAAAAAAAAAAAAA\
    AAAAAAAAA
    AAAAACH5BAEAAAAALAAAAAALAAwAAAQmEIQxgLVUCsppsVPngVtXEFfIfWk5nBe4xuSL0t\
    KLy/cu
    7JffJQIAOw==
    '''
    

    LEFT_GIF

    Value:
    '''R0lGODlhDAALAKIAANnZ2QDMmQCZZgBmZgAAAAAzM////////yH5BAEAAAAALAAAAAA\
    MAAsAAAM4
    CLocgaCrESiDoBshOAoAgBEyMzgAEIGCowsiOLoLgEBVOLoIqlSFo4OgC1RYM4Ogq1RYg6\
    DLVJgA
    Ow==
    '''
    

    RIGHT_GIF

    Value:
    '''R0lGODlhDAALAKIAANnZ2QDMmQBmZgCZZgAzMwAAAP///////yH5BAEAAAAALAAAAAA\
    MAAsAAAM5
    GIGgyzIYgaCrIigTgaALIigyEQiqKLoTgaAoujuDgKJLVAgqIoJEBQAIIkKEhaArRFgIuk\
    qFoMsJ
    ADs=
    '''
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.ClassMethodDoc-class.html0000644000175000017500000007073310750103050025061 0ustar pronovicpronovic epydoc.apidoc.ClassMethodDoc
    Package epydoc :: Module apidoc :: Class ClassMethodDoc
    [hide private]
    [frames] | no frames]

    Class ClassMethodDoc

    source code


    Instance Methods [hide private]

    Inherited from RoutineDoc: all_args, is_detailed

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__, apidoc_links

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from RoutineDoc: callgraph_uid

    Inherited from ValueDoc: canonical_name, toktree

        Signature

    Inherited from RoutineDoc: kwarg, lineno, posarg_defaults, posargs, vararg

        Decorators

    Inherited from RoutineDoc: decorators

        Information Extracted from Docstrings

    Inherited from RoutineDoc: arg_descrs, arg_types, exception_descrs, return_descr, return_type

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    epydoc-3.0.1+dfsg/doc/api/identifier-index.html0000644000175000017500000121625110750103050021627 0ustar pronovicpronovic Identifier Index
     
    [hide private]
    [frames] | no frames]
    [ Identifiers | Term Definitions | Bugs | To Do ]

    Identifier Index

    [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

    A

    B

    C

    D

    E

    F

    G

    H

    I

    J

    K

    L

    M

    N

    O

    P

    Q

    R

    S

    T

    U

    V

    W

    X

    Y

    _



    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.html-module.html0000644000175000017500000000274410750103050024674 0ustar pronovicpronovic html

    Module html


    Classes

    HTMLWriter

    Functions

    compile_template
    strip_indent

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.ModuleDoc-class.html0000644000175000017500000015506310750103050024100 0ustar pronovicpronovic epydoc.apidoc.ModuleDoc
    Package epydoc :: Module apidoc :: Class ModuleDoc
    [hide private]
    [frames] | no frames]

    Class ModuleDoc

    source code


    API documentation information about a single module.

    Instance Methods [hide private]
     
    apidoc_links(self, **filters)
    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
    source code
    call graph 
     
    init_submodule_groups(self)
    Initialize the submodule_groups attribute, based on the submodules and group_specs attributes.
    source code
    call graph 
     
    select_variables(self, group=None, value_type=None, public=None, imported=None, detailed=None)
    Return a specified subset of this module's sorted_variables list.
    source code
    call graph 

    Inherited from NamespaceDoc: __init__, group_names, init_sorted_variables, init_variable_groups, is_detailed, report_unused_groups

    Inherited from NamespaceDoc (private): _init_grouping

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__

    Inherited from APIDoc: __cmp__, __hash__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from ValueDoc: canonical_name, toktree

        Information about the Module
    string filename = _Sentinel('UNKNOWN')
    The name of the file that defines the module.
    string docformat = _Sentinel('UNKNOWN')
    The markup language used by docstrings in this module.
        Information about Submodules
    list of ModuleDoc submodules = _Sentinel('UNKNOWN')
    Modules contained by this module (if this module is a package).
    dict from str to list of ModuleDoc submodule_groups = _Sentinel('UNKNOWN')
    A dictionary specifying what group each submodule belongs to.
        Information about Packages
    ModuleDoc package = _Sentinel('UNKNOWN')
    API documentation for the module's containing package.
    bool is_package = _Sentinel('UNKNOWN')
    True if this ModuleDoc describes a package.
    list of str path = _Sentinel('UNKNOWN')
    If this ModuleDoc describes a package, then path contains a list of directories that constitute its path (i.e., the value of its __path__ variable).
        Information about Imported Variables
    list of DottedName imports = _Sentinel('UNKNOWN')
    A list of the source names of variables imported into this module.

    Inherited from ValueDoc: proxy_for

        Information about Variables

    Inherited from NamespaceDoc: group_specs, sort_spec, sorted_variables, variable_groups, variables

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Information Extracted from Docstrings

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    apidoc_links(self, **filters)

    source code 
    call graph 

    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

    Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

    • imports: Imported variables.
    • packages: Containing packages for modules.
    • submodules: Contained submodules for packages.
    • bases: Bases for classes.
    • subclasses: Subclasses for classes.
    • variables: All variables.
    • private: Private variables.
    • overrides: Points from class variables to the variables they override. This filter is False by default.
    Overrides: APIDoc.apidoc_links
    (inherited documentation)

    select_variables(self, group=None, value_type=None, public=None, imported=None, detailed=None)

    source code 
    call graph 

    Return a specified subset of this module's sorted_variables list. If value_type is given, then only return variables whose values have the specified type. If group is given, then only return variables that belong to the specified group.

    Parameters:
    • value_type (string) - A string specifying the value type for which variables should be returned. Valid values are:
      • 'class' - variables whose values are classes or types.
      • 'function' - variables whose values are functions.
      • 'other' - variables whose values are not classes, exceptions, types, or functions.
    • group (string) - The name of the group for which variables should be returned. A complete list of the groups defined by this ModuleDoc is available in the group_names instance variable. The first element of this list is always the special group name '', which is used for variables that do not belong to any group.
    • detailed (bool) - If True (False), return only the variables deserving (not deserving) a detailed informative box. If None, don't care.

    Requires: The sorted_variables, variable_groups, and submodule_groups attributes must be initialized before this method can be used. See init_sorted_variables(), init_variable_groups(), and init_submodule_groups().


    Instance Variable Details [hide private]

    submodules

    Modules contained by this module (if this module is a package). (Note: on rare occasions, a module may have a submodule that is shadowed by a variable with the same name.)
    Type:
    list of ModuleDoc
    Value:
    _Sentinel('UNKNOWN')
    

    submodule_groups

    A dictionary specifying what group each submodule belongs to. The keys of the dictionary are group names, and the values are lists of ModuleDocs. The order that groups should be listed in should be taken from group_specs.
    Type:
    dict from str to list of ModuleDoc
    Value:
    _Sentinel('UNKNOWN')
    

    imports

    A list of the source names of variables imported into this module. This is used to construct import graphs.
    Type:
    list of DottedName
    Value:
    _Sentinel('UNKNOWN')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.checker-pysrc.html0000644000175000017500000035134610750103050022430 0ustar pronovicpronovic epydoc.checker
    Package epydoc :: Module checker
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.checker

      1  # 
      2  # objdoc: epydoc documentation completeness checker 
      3  # Edward Loper 
      4  # 
      5  # Created [01/30/01 05:18 PM] 
      6  # $Id: checker.py 1366 2006-09-07 15:54:59Z edloper $ 
      7  # 
      8   
      9  """ 
     10  Documentation completeness checker.  This module defines a single 
     11  class, C{DocChecker}, which can be used to check the that specified 
     12  classes of objects are documented. 
     13  """ 
     14  __docformat__ = 'epytext en' 
     15   
     16  ################################################## 
     17  ## Imports 
     18  ################################################## 
     19   
     20  import re, sys, os.path, string 
     21  from xml.dom.minidom import Text as _Text 
     22  from epydoc.apidoc import * 
     23   
     24  # The following methods may be undocumented: 
     25  _NO_DOCS = ['__hash__', '__repr__', '__str__', '__cmp__'] 
     26   
     27  # The following methods never need descriptions, authors, or 
     28  # versions: 
     29  _NO_BASIC = ['__hash__', '__repr__', '__str__', '__cmp__'] 
     30   
     31  # The following methods never need return value descriptions. 
     32  _NO_RETURN = ['__init__', '__hash__', '__repr__', '__str__', '__cmp__'] 
     33   
     34  # The following methods don't need parameters documented: 
     35  _NO_PARAM = ['__cmp__'] 
     36   
    
    37 -class DocChecker:
    38 """ 39 Documentation completeness checker. C{DocChecker} can be used to 40 check that specified classes of objects are documented. To check 41 the documentation for a group of objects, you should create a 42 C{DocChecker} from a L{DocIndex<apidoc.DocIndex>} that documents 43 those objects; and then use the L{check} method to run specified 44 checks on the objects' documentation. 45 46 What checks are run, and what objects they are run on, are 47 specified by the constants defined by C{DocChecker}. These 48 constants are divided into three groups. 49 50 - Type specifiers indicate what type of objects should be 51 checked: L{MODULE}; L{CLASS}; L{FUNC}; L{VAR}; L{IVAR}; 52 L{CVAR}; L{PARAM}; and L{RETURN}. 53 - Public/private specifiers indicate whether public or private 54 objects should be checked: L{PRIVATE}. 55 - Check specifiers indicate what checks should be run on the 56 objects: L{TYPE}; L{DESCR}; L{AUTHOR}; 57 and L{VERSION}. 58 59 The L{check} method is used to perform a check on the 60 documentation. Its parameter is formed by or-ing together at 61 least one value from each specifier group: 62 63 >>> checker.check(DocChecker.MODULE | DocChecker.DESCR) 64 65 To specify multiple values from a single group, simply or their 66 values together: 67 68 >>> checker.check(DocChecker.MODULE | DocChecker.CLASS | 69 ... DocChecker.FUNC ) 70 71 @group Types: MODULE, CLASS, FUNC, VAR, IVAR, CVAR, PARAM, 72 RETURN, ALL_T 73 @type MODULE: C{int} 74 @cvar MODULE: Type specifier that indicates that the documentation 75 of modules should be checked. 76 @type CLASS: C{int} 77 @cvar CLASS: Type specifier that indicates that the documentation 78 of classes should be checked. 79 @type FUNC: C{int} 80 @cvar FUNC: Type specifier that indicates that the documentation 81 of functions should be checked. 82 @type VAR: C{int} 83 @cvar VAR: Type specifier that indicates that the documentation 84 of module variables should be checked. 85 @type IVAR: C{int} 86 @cvar IVAR: Type specifier that indicates that the documentation 87 of instance variables should be checked. 88 @type CVAR: C{int} 89 @cvar CVAR: Type specifier that indicates that the documentation 90 of class variables should be checked. 91 @type PARAM: C{int} 92 @cvar PARAM: Type specifier that indicates that the documentation 93 of function and method parameters should be checked. 94 @type RETURN: C{int} 95 @cvar RETURN: Type specifier that indicates that the documentation 96 of return values should be checked. 97 @type ALL_T: C{int} 98 @cvar ALL_T: Type specifier that indicates that the documentation 99 of all objects should be checked. 100 101 @group Checks: TYPE, AUTHOR, VERSION, DESCR, ALL_C 102 @type TYPE: C{int} 103 @cvar TYPE: Check specifier that indicates that every variable and 104 parameter should have a C{@type} field. 105 @type AUTHOR: C{int} 106 @cvar AUTHOR: Check specifier that indicates that every object 107 should have an C{author} field. 108 @type VERSION: C{int} 109 @cvar VERSION: Check specifier that indicates that every object 110 should have a C{version} field. 111 @type DESCR: C{int} 112 @cvar DESCR: Check specifier that indicates that every object 113 should have a description. 114 @type ALL_C: C{int} 115 @cvar ALL_C: Check specifier that indicates that all checks 116 should be run. 117 118 @group Publicity: PRIVATE 119 @type PRIVATE: C{int} 120 @cvar PRIVATE: Specifier that indicates that private objects should 121 be checked. 122 """ 123 # Types 124 MODULE = 1 125 CLASS = 2 126 FUNC = 4 127 VAR = 8 128 #IVAR = 16 129 #CVAR = 32 130 PARAM = 64 131 RETURN = 128 132 PROPERTY = 256 133 ALL_T = 1+2+4+8+16+32+64+128+256 134 135 # Checks 136 TYPE = 256 137 AUTHOR = 1024 138 VERSION = 2048 139 DESCR = 4096 140 ALL_C = 256+512+1024+2048+4096 141 142 # Private/public 143 PRIVATE = 16384 144 145 ALL = ALL_T + ALL_C + PRIVATE 146
    147 - def __init__(self, docindex):
    148 """ 149 Create a new C{DocChecker} that can be used to run checks on 150 the documentation of the objects documented by C{docindex} 151 152 @param docindex: A documentation map containing the 153 documentation for the objects to be checked. 154 @type docindex: L{Docindex<apidoc.DocIndex>} 155 """ 156 self._docindex = docindex 157 158 # Initialize instance variables 159 self._checks = 0 160 self._last_warn = None 161 self._out = sys.stdout 162 self._num_warnings = 0
    163
    164 - def check(self, *check_sets):
    165 """ 166 Run the specified checks on the documentation of the objects 167 contained by this C{DocChecker}'s C{DocIndex}. Any errors found 168 are printed to standard out. 169 170 @param check_sets: The checks that should be run on the 171 documentation. This value is constructed by or-ing 172 together the specifiers that indicate which objects should 173 be checked, and which checks should be run. See the 174 L{module description<checker>} for more information. 175 If no checks are specified, then a default set of checks 176 will be run. 177 @type check_sets: C{int} 178 @return: True if no problems were found. 179 @rtype: C{boolean} 180 """ 181 if not check_sets: 182 check_sets = (DocChecker.MODULE | DocChecker.CLASS | 183 DocChecker.FUNC | DocChecker.VAR | 184 DocChecker.DESCR,) 185 186 self._warnings = {} 187 log.start_progress('Checking docs') 188 for j, checks in enumerate(check_sets): 189 self._check(checks) 190 log.end_progress() 191 192 for (warning, docs) in self._warnings.items(): 193 docs = sorted(docs) 194 docnames = '\n'.join([' - %s' % self._name(d) for d in docs]) 195 log.warning('%s:\n%s' % (warning, docnames))
    196
    197 - def _check(self, checks):
    198 self._checks = checks 199 200 # Get the list of objects to check. 201 valdocs = sorted(self._docindex.reachable_valdocs( 202 imports=False, packages=False, bases=False, submodules=False, 203 subclasses=False, private = (checks & DocChecker.PRIVATE))) 204 docs = set() 205 for d in valdocs: 206 if not isinstance(d, GenericValueDoc): docs.add(d) 207 for doc in valdocs: 208 if isinstance(doc, NamespaceDoc): 209 for d in doc.variables.values(): 210 if isinstance(d.value, GenericValueDoc): docs.add(d) 211 212 for i, doc in enumerate(sorted(docs)): 213 if isinstance(doc, ModuleDoc): 214 self._check_module(doc) 215 elif isinstance(doc, ClassDoc): 216 self._check_class(doc) 217 elif isinstance(doc, RoutineDoc): 218 self._check_func(doc) 219 elif isinstance(doc, PropertyDoc): 220 self._check_property(doc) 221 elif isinstance(doc, VariableDoc): 222 self._check_var(doc) 223 else: 224 log.error("Don't know how to check %r" % doc)
    225
    226 - def _name(self, doc):
    227 name = str(doc.canonical_name) 228 if isinstance(doc, RoutineDoc): name += '()' 229 return name
    230
    231 - def _check_basic(self, doc):
    232 """ 233 Check the description, author, version, and see-also fields of 234 C{doc}. This is used as a helper function by L{_check_module}, 235 L{_check_class}, and L{_check_func}. 236 237 @param doc: The documentation that should be checked. 238 @type doc: L{APIDoc} 239 @rtype: C{None} 240 """ 241 if ((self._checks & DocChecker.DESCR) and 242 (doc.descr in (None, UNKNOWN))): 243 if doc.docstring in (None, UNKNOWN): 244 self.warning('Undocumented', doc) 245 else: 246 self.warning('No description', doc) 247 if self._checks & DocChecker.AUTHOR: 248 for tag, arg, descr in doc.metadata: 249 if 'author' == tag: break 250 else: 251 self.warning('No authors', doc) 252 if self._checks & DocChecker.VERSION: 253 for tag, arg, descr in doc.metadata: 254 if 'version' == tag: break 255 else: 256 self.warning('No version', doc)
    257
    258 - def _check_module(self, doc):
    259 """ 260 Run checks on the module whose APIDoc is C{doc}. 261 262 @param doc: The APIDoc of the module to check. 263 @type doc: L{APIDoc} 264 @rtype: C{None} 265 """ 266 if self._checks & DocChecker.MODULE: 267 self._check_basic(doc)
    268
    269 - def _check_class(self, doc):
    270 """ 271 Run checks on the class whose APIDoc is C{doc}. 272 273 @param doc: The APIDoc of the class to check. 274 @type doc: L{APIDoc} 275 @rtype: C{None} 276 """ 277 if self._checks & DocChecker.CLASS: 278 self._check_basic(doc)
    279
    280 - def _check_property(self, doc):
    281 if self._checks & DocChecker.PROPERTY: 282 self._check_basic(doc)
    283
    284 - def _check_var(self, doc):
    285 """ 286 Run checks on the variable whose documentation is C{var} and 287 whose name is C{name}. 288 289 @param doc: The documentation for the variable to check. 290 @type doc: L{APIDoc} 291 @rtype: C{None} 292 """ 293 if self._checks & DocChecker.VAR: 294 if (self._checks & (DocChecker.DESCR|DocChecker.TYPE) and 295 doc.descr in (None, UNKNOWN) and 296 doc.type_descr in (None, UNKNOWN) and 297 doc.docstring in (None, UNKNOWN)): 298 self.warning('Undocumented', doc) 299 else: 300 if (self._checks & DocChecker.DESCR and 301 doc.descr in (None, UNKNOWN)): 302 self.warning('No description', doc) 303 if (self._checks & DocChecker.TYPE and 304 doc.type_descr in (None, UNKNOWN)): 305 self.warning('No type information', doc)
    306
    307 - def _check_func(self, doc):
    308 """ 309 Run checks on the function whose APIDoc is C{doc}. 310 311 @param doc: The APIDoc of the function to check. 312 @type doc: L{APIDoc} 313 @rtype: C{None} 314 """ 315 name = doc.canonical_name 316 if (self._checks & DocChecker.FUNC and 317 doc.docstring in (None, UNKNOWN) and 318 doc.canonical_name[-1] not in _NO_DOCS): 319 self.warning('Undocumented', doc) 320 return 321 if (self._checks & DocChecker.FUNC and 322 doc.canonical_name[-1] not in _NO_BASIC): 323 self._check_basic(doc) 324 if (self._checks & DocChecker.RETURN and 325 doc.canonical_name[-1] not in _NO_RETURN): 326 if (doc.return_type in (None, UNKNOWN) and 327 doc.return_descr in (None, UNKNOWN)): 328 self.warning('No return descr', doc) 329 if (self._checks & DocChecker.PARAM and 330 doc.canonical_name[-1] not in _NO_PARAM): 331 if doc.arg_descrs in (None, UNKNOWN): 332 self.warning('No argument info', doc) 333 else: 334 args_with_descr = [] 335 for arg, descr in doc.arg_descrs: 336 if isinstance(arg, basestring): 337 args_with_descr.append(arg) 338 else: 339 args_with_descr += arg 340 for posarg in doc.posargs: 341 if (self._checks & DocChecker.DESCR and 342 posarg not in args_with_descr): 343 self.warning('Argument(s) not described', doc) 344 if (self._checks & DocChecker.TYPE and 345 posarg not in doc.arg_types): 346 self.warning('Argument type(s) not described', doc)
    347
    348 - def warning(self, msg, doc):
    349 self._warnings.setdefault(msg,set()).add(doc)
    350

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._EpydocHTMLTranslator-class.html0000644000175000017500000015701110750103050032040 0ustar pronovicpronovic epydoc.markup.restructuredtext._EpydocHTMLTranslator
    Package epydoc :: Package markup :: Module restructuredtext :: Class _EpydocHTMLTranslator
    [hide private]
    [frames] | no frames]

    Class _EpydocHTMLTranslator

    source code


    Instance Methods [hide private]
     
    __init__(self, document, docstring_linker, directory, docindex, context) source code
    call graph 
     
    visit_title_reference(self, node) source code
    call graph 
     
    should_be_compact_paragraph(self, node)
    Determine if the <p> tags around paragraph node can be omitted.
    source code
    call graph 
     
    visit_document(self, node) source code
    call graph 
     
    depart_document(self, node) source code
    call graph 
     
    starttag(self, node, tagname, suffix='\n', **attributes)
    This modified version of starttag makes a few changes to HTML tags, to prevent them from conflicting with epydoc.
    source code
    call graph 
     
    visit_dotgraph(self, node) source code
    call graph 
     
    visit_doctest_block(self, node) source code
     
    visit_emphasis(self, node) source code
    call graph 

    Inherited from docutils.writers.html4css1.HTMLTranslator: add_meta, astext, attval, check_simple_list, cloak_email, cloak_mailto, depart_Text, depart_abbreviation, depart_acronym, depart_address, depart_admonition, depart_attribution, depart_author, depart_authors, depart_block_quote, depart_bullet_list, depart_caption, depart_citation, depart_citation_reference, depart_classifier, depart_colspec, depart_compound, depart_contact, depart_container, depart_copyright, depart_date, depart_decoration, depart_definition, depart_definition_list, depart_definition_list_item, depart_description, depart_docinfo, depart_docinfo_item, depart_doctest_block, depart_emphasis, depart_entry, depart_enumerated_list, depart_field, depart_field_body, depart_field_list, depart_field_name, depart_figure, depart_footer, depart_footnote, depart_footnote_reference, depart_generated, depart_header, depart_image, depart_inline, depart_label, depart_legend, depart_line, depart_line_block, depart_list_item, depart_literal_block, depart_meta, depart_option, depart_option_argument, depart_option_group, depart_option_list, depart_option_list_item, depart_option_string, depart_organization, depart_paragraph, depart_problematic, depart_reference, depart_revision, depart_row, depart_rubric, depart_section, depart_sidebar, depart_status, depart_strong, depart_subscript, depart_subtitle, depart_superscript, depart_system_message, depart_table, depart_target, depart_tbody, depart_term, depart_tgroup, depart_thead, depart_title, depart_title_reference, depart_topic, depart_transition, depart_version, emptytag, encode, footnote_backrefs, is_compactable, set_class_on_child, set_first_last, unimplemented_visit, visit_Text, visit_abbreviation, visit_acronym, visit_address, visit_admonition, visit_attribution, visit_author, visit_authors, visit_block_quote, visit_bullet_list, visit_caption, visit_citation, visit_citation_reference, visit_classifier, visit_colspec, visit_comment, visit_compound, visit_contact, visit_container, visit_copyright, visit_date, visit_decoration, visit_definition, visit_definition_list, visit_definition_list_item, visit_description, visit_docinfo, visit_docinfo_item, visit_entry, visit_enumerated_list, visit_field, visit_field_body, visit_field_list, visit_field_name, visit_figure, visit_footer, visit_footnote, visit_footnote_reference, visit_generated, visit_header, visit_image, visit_inline, visit_label, visit_legend, visit_line, visit_line_block, visit_list_item, visit_literal, visit_literal_block, visit_meta, visit_option, visit_option_argument, visit_option_group, visit_option_list, visit_option_list_item, visit_option_string, visit_organization, visit_paragraph, visit_problematic, visit_raw, visit_reference, visit_revision, visit_row, visit_rubric, visit_section, visit_sidebar, visit_status, visit_strong, visit_subscript, visit_substitution_definition, visit_substitution_reference, visit_subtitle, visit_superscript, visit_system_message, visit_table, visit_target, visit_tbody, visit_term, visit_tgroup, visit_thead, visit_title, visit_topic, visit_transition, visit_version, write_colspecs

    Inherited from docutils.nodes.NodeVisitor: dispatch_departure, dispatch_visit, unknown_departure, unknown_visit

    Class Variables [hide private]
      settings = None

    Inherited from docutils.writers.html4css1.HTMLTranslator: attribution_formats, content_type, doctype, embedded_stylesheet, generator, head_prefix_template, stylesheet_link, words_and_spaces, xml_declaration

    Inherited from docutils.nodes.NodeVisitor: optional

    Method Details [hide private]

    __init__(self, document, docstring_linker, directory, docindex, context)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.nodes.NodeVisitor.__init__

    visit_title_reference(self, node)

    source code 
    call graph 
    Overrides: docutils.writers.html4css1.HTMLTranslator.visit_title_reference

    should_be_compact_paragraph(self, node)

    source code 
    call graph 
    Determine if the <p> tags around paragraph node can be omitted.
    Overrides: docutils.writers.html4css1.HTMLTranslator.should_be_compact_paragraph
    (inherited documentation)

    visit_document(self, node)

    source code 
    call graph 
    Overrides: docutils.writers.html4css1.HTMLTranslator.visit_document

    depart_document(self, node)

    source code 
    call graph 
    Overrides: docutils.writers.html4css1.HTMLTranslator.depart_document

    starttag(self, node, tagname, suffix='\n', **attributes)

    source code 
    call graph 

    This modified version of starttag makes a few changes to HTML tags, to prevent them from conflicting with epydoc. In particular:

    • existing class attributes are prefixed with 'rst-'
    • existing names are prefixed with 'rst-'
    • hrefs starting with '#' are prefixed with 'rst-'
    • hrefs not starting with '#' are given target='_top'
    • all headings (<hn>) are given the css class 'heading'
    Overrides: docutils.writers.html4css1.HTMLTranslator.starttag

    visit_doctest_block(self, node)

    source code 
    Overrides: docutils.writers.html4css1.HTMLTranslator.visit_doctest_block

    visit_emphasis(self, node)

    source code 
    call graph 
    Overrides: docutils.writers.html4css1.HTMLTranslator.visit_emphasis

    epydoc-3.0.1+dfsg/doc/api/epydoc.util-module.html0000644000175000017500000012470710750103050022125 0ustar pronovicpronovic epydoc.util
    Package epydoc :: Module util
    [hide private]
    [frames] | no frames]

    Module util

    source code

    Miscellaneous utility functions that are used by multiple modules.

    Classes [hide private]
      RunSubprocessError
    Functions [hide private]
     
    is_src_filename(filename) source code
    call graph 
     
    munge_script_name(filename) source code
    string
    plaintext_to_latex(str, nbsp=0, breakany=0)
    Returns: A LaTeX string that encodes the given plaintext string.
    source code
     
    run_subprocess(cmd, data=None)
    Execute the command cmd in a subprocess.
    source code
    call graph 
        Python source types
     
    is_module_file(path) source code
    call graph 
     
    is_package_dir(dirname)
    Return true if the given directory is a valid package directory (i.e., it names a directory that contains a valid __init__ file, and its name is a valid identifier).
    source code
    call graph 
     
    is_pyname(name) source code
     
    py_src_filename(filename) source code
    call graph 
        Text processing
     
    decode_with_backslashreplace(s)
    Convert the given 8-bit string into unicode, treating any character c such that ord(c)<128 as an ascii character, and converting any c such that ord(c)>128 into a backslashed escape sequence.
    source code
    call graph 
    str
    wordwrap(str, indent=0, right=75, startindex=0, splitchars='')
    Word-wrap the given string.
    source code
    call graph 
    string
    plaintext_to_html(s)
    Returns: An HTML string that encodes the given plaintext string.
    source code
    call graph 
    Variables [hide private]
      PY_SRC_EXTENSIONS = ['.py', '.pyw']
      PY_BIN_EXTENSIONS = ['.pyc', '.so', '.pyd']
    Function Details [hide private]

    decode_with_backslashreplace(s)

    source code 
    call graph 

    Convert the given 8-bit string into unicode, treating any character c such that ord(c)<128 as an ascii character, and converting any c such that ord(c)>128 into a backslashed escape sequence.

    >>> decode_with_backslashreplace('abc\xff\xe8')
    u'abc\\xff\\xe8'

    wordwrap(str, indent=0, right=75, startindex=0, splitchars='')

    source code 
    call graph 

    Word-wrap the given string. I.e., add newlines to the string such that any lines that are longer than right are broken into shorter lines (at the first whitespace sequence that occurs before index right). If the given string contains newlines, they will not be removed. Any lines that begin with whitespace will not be wordwrapped.

    Parameters:
    • indent (int) - If specified, then indent each line by this number of spaces.
    • right (int) - The right margin for word wrapping. Lines that are longer than right will be broken at the first whitespace sequence before the right margin.
    • startindex (int) - If specified, then assume that the first line is already preceeded by startindex characters.
    • splitchars - A list of non-whitespace characters which can be used to split a line. (E.g., use '/\' to allow path names to be split over multiple lines.)
    Returns: str

    plaintext_to_html(s)

    source code 
    call graph 
    Returns: string
    An HTML string that encodes the given plaintext string. In particular, special characters (such as '<' and '&') are escaped.

    plaintext_to_latex(str, nbsp=0, breakany=0)

    source code 
    Parameters:
    • breakany - Insert hyphenation marks, so that LaTeX can break the resulting string at any point. This is useful for small boxes (e.g., the type box in the variable list table).
    • nbsp - Replace every space with a non-breaking space ('~').
    Returns: string
    A LaTeX string that encodes the given plaintext string. In particular, special characters (such as '$' and '_') are escaped, and tabs are expanded.

    run_subprocess(cmd, data=None)

    source code 
    call graph 

    Execute the command cmd in a subprocess.

    Parameters:
    • cmd - The command to execute, specified as a list of string.
    • data - A string containing data to send to the subprocess.
    Returns:
    A tuple (out, err).
    Raises:
    • OSError - If there is any problem executing the command, or if its exitval is not 0.

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest-pysrc.html0000644000175000017500000030720610750103050023763 0ustar pronovicpronovic epydoc.markup.doctest
    Package epydoc :: Package markup :: Module doctest
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.markup.doctest

      1  # 
      2  # doctest.py: Syntax Highlighting for doctest blocks 
      3  # Edward Loper 
      4  # 
      5  # Created [06/28/03 02:52 AM] 
      6  # $Id: restructuredtext.py 1210 2006-04-10 13:25:50Z edloper $ 
      7  # 
      8   
      9  """ 
     10  Syntax highlighting for doctest blocks.  This module defines two 
     11  functions, L{doctest_to_html()} and L{doctest_to_latex()}, which can 
     12  be used to perform syntax highlighting on doctest blocks.  It also 
     13  defines the more general C{colorize_doctest()}, which could be used to 
     14  do syntac highlighting on doctest blocks with other output formats. 
     15  (Both C{doctest_to_html()} and C{doctest_to_latex()} are defined using 
     16  C{colorize_doctest()}.) 
     17  """ 
     18  __docformat__ = 'epytext en' 
     19   
     20  import re 
     21  from epydoc.util import plaintext_to_html, plaintext_to_latex 
     22   
     23  __all__ = ['doctest_to_html', 'doctest_to_latex', 
     24             'DoctestColorizer', 'XMLDoctestColorizer',  
     25             'HTMLDoctestColorizer', 'LaTeXDoctestColorizer'] 
     26   
    
    27 -def doctest_to_html(s):
    28 """ 29 Perform syntax highlighting on the given doctest string, and 30 return the resulting HTML code. This code consists of a C{<pre>} 31 block with class=py-doctest. Syntax highlighting is performed 32 using the following css classes: 33 34 - C{py-prompt} -- the Python PS1 prompt (>>>) 35 - C{py-more} -- the Python PS2 prompt (...) 36 - C{py-keyword} -- a Python keyword (for, if, etc.) 37 - C{py-builtin} -- a Python builtin name (abs, dir, etc.) 38 - C{py-string} -- a string literal 39 - C{py-comment} -- a comment 40 - C{py-except} -- an exception traceback (up to the next >>>) 41 - C{py-output} -- the output from a doctest block. 42 - C{py-defname} -- the name of a function or class defined by 43 a C{def} or C{class} statement. 44 """ 45 return HTMLDoctestColorizer().colorize_doctest(s)
    46
    47 -def doctest_to_latex(s):
    48 """ 49 Perform syntax highlighting on the given doctest string, and 50 return the resulting LaTeX code. This code consists of an 51 C{alltt} environment. Syntax highlighting is performed using 52 the following new latex commands, which must be defined externally: 53 - C{\pysrcprompt} -- the Python PS1 prompt (>>>) 54 - C{\pysrcmore} -- the Python PS2 prompt (...) 55 - C{\pysrckeyword} -- a Python keyword (for, if, etc.) 56 - C{\pysrcbuiltin} -- a Python builtin name (abs, dir, etc.) 57 - C{\pysrcstring} -- a string literal 58 - C{\pysrccomment} -- a comment 59 - C{\pysrcexcept} -- an exception traceback (up to the next >>>) 60 - C{\pysrcoutput} -- the output from a doctest block. 61 - C{\pysrcdefname} -- the name of a function or class defined by 62 a C{def} or C{class} statement. 63 """ 64 return LaTeXDoctestColorizer().colorize_doctest(s)
    65
    66 -class DoctestColorizer:
    67 """ 68 An abstract base class for performing syntax highlighting on 69 doctest blocks and other bits of Python code. Subclasses should 70 provide definitions for: 71 72 - The L{markup()} method, which takes a substring and a tag, and 73 returns a colorized version of the substring. 74 - The L{PREFIX} and L{SUFFIX} variables, which will be added 75 to the beginning and end of the strings returned by 76 L{colorize_codeblock} and L{colorize_doctest}. 77 """ 78 79 #: A string that is added to the beginning of the strings 80 #: returned by L{colorize_codeblock} and L{colorize_doctest}. 81 #: Typically, this string begins a preformatted area. 82 PREFIX = None 83 84 #: A string that is added to the end of the strings 85 #: returned by L{colorize_codeblock} and L{colorize_doctest}. 86 #: Typically, this string ends a preformatted area. 87 SUFFIX = None 88 89 #: A list of the names of all Python keywords. ('as' is included 90 #: even though it is technically not a keyword.) 91 _KEYWORDS = ("and del for is raise" 92 "assert elif from lambda return" 93 "break else global not try" 94 "class except if or while" 95 "continue exec import pass yield" 96 "def finally in print as").split() 97 98 #: A list of all Python builtins. 99 _BUILTINS = [_BI for _BI in dir(__builtins__) 100 if not _BI.startswith('__')] 101 102 #: A regexp group that matches keywords. 103 _KEYWORD_GRP = '|'.join([r'\b%s\b' % _KW for _KW in _KEYWORDS]) 104 105 #: A regexp group that matches Python builtins. 106 _BUILTIN_GRP = (r'(?<!\.)(?:%s)' % '|'.join([r'\b%s\b' % _BI 107 for _BI in _BUILTINS])) 108 109 #: A regexp group that matches Python strings. 110 _STRING_GRP = '|'.join( 111 [r'("""("""|.*?((?!").)"""))', r'("("|.*?((?!").)"))', 112 r"('''('''|.*?[^\\']'''))", r"('('|.*?[^\\']'))"]) 113 114 #: A regexp group that matches Python comments. 115 _COMMENT_GRP = '(#.*?$)' 116 117 #: A regexp group that matches Python ">>>" prompts. 118 _PROMPT1_GRP = r'^[ \t]*>>>(?:[ \t]|$)' 119 120 #: A regexp group that matches Python "..." prompts. 121 _PROMPT2_GRP = r'^[ \t]*\.\.\.(?:[ \t]|$)' 122 123 #: A regexp group that matches function and class definitions. 124 _DEFINE_GRP = r'\b(?:def|class)[ \t]+\w+' 125 126 #: A regexp that matches Python prompts 127 PROMPT_RE = re.compile('(%s|%s)' % (_PROMPT1_GRP, _PROMPT2_GRP), 128 re.MULTILINE | re.DOTALL) 129 130 #: A regexp that matches Python "..." prompts. 131 PROMPT2_RE = re.compile('(%s)' % _PROMPT2_GRP, 132 re.MULTILINE | re.DOTALL) 133 134 #: A regexp that matches doctest exception blocks. 135 EXCEPT_RE = re.compile(r'^[ \t]*Traceback \(most recent call last\):.*', 136 re.DOTALL | re.MULTILINE) 137 138 #: A regexp that matches doctest directives. 139 DOCTEST_DIRECTIVE_RE = re.compile(r'#[ \t]*doctest:.*') 140 141 #: A regexp that matches all of the regions of a doctest block 142 #: that should be colored. 143 DOCTEST_RE = re.compile( 144 r'(.*?)((?P<STRING>%s)|(?P<COMMENT>%s)|(?P<DEFINE>%s)|' 145 r'(?P<KEYWORD>%s)|(?P<BUILTIN>%s)|' 146 r'(?P<PROMPT1>%s)|(?P<PROMPT2>%s)|(?P<EOS>\Z))' % ( 147 _STRING_GRP, _COMMENT_GRP, _DEFINE_GRP, _KEYWORD_GRP, _BUILTIN_GRP, 148 _PROMPT1_GRP, _PROMPT2_GRP), re.MULTILINE | re.DOTALL) 149 150 #: This regular expression is used to find doctest examples in a 151 #: string. This is copied from the standard Python doctest.py 152 #: module (after the refactoring in Python 2.4+). 153 DOCTEST_EXAMPLE_RE = re.compile(r''' 154 # Source consists of a PS1 line followed by zero or more PS2 lines. 155 (?P<source> 156 (?:^(?P<indent> [ ]*) >>> .*) # PS1 line 157 (?:\n [ ]* \.\.\. .*)* # PS2 lines 158 \n?) 159 # Want consists of any non-blank lines that do not start with PS1. 160 (?P<want> (?:(?![ ]*$) # Not a blank line 161 (?![ ]*>>>) # Not a line starting with PS1 162 .*$\n? # But any other line 163 )*) 164 ''', re.MULTILINE | re.VERBOSE) 165
    166 - def colorize_inline(self, s):
    167 """ 168 Colorize a string containing Python code. Do not add the 169 L{PREFIX} and L{SUFFIX} strings to the returned value. This 170 method is intended for generating syntax-highlighted strings 171 that are appropriate for inclusion as inline expressions. 172 """ 173 return self.DOCTEST_RE.sub(self.subfunc, s)
    174
    175 - def colorize_codeblock(self, s):
    176 """ 177 Colorize a string containing only Python code. This method 178 differs from L{colorize_doctest} in that it will not search 179 for doctest prompts when deciding how to colorize the string. 180 """ 181 body = self.DOCTEST_RE.sub(self.subfunc, s) 182 return self.PREFIX + body + self.SUFFIX
    183
    184 - def colorize_doctest(self, s, strip_directives=False):
    185 """ 186 Colorize a string containing one or more doctest examples. 187 """ 188 output = [] 189 charno = 0 190 for m in self.DOCTEST_EXAMPLE_RE.finditer(s): 191 # Parse the doctest example: 192 pysrc, want = m.group('source', 'want') 193 # Pre-example text: 194 output.append(s[charno:m.start()]) 195 # Example source code: 196 output.append(self.DOCTEST_RE.sub(self.subfunc, pysrc)) 197 # Example output: 198 if want: 199 if self.EXCEPT_RE.match(want): 200 output += '\n'.join([self.markup(line, 'except') 201 for line in want.split('\n')]) 202 else: 203 output += '\n'.join([self.markup(line, 'output') 204 for line in want.split('\n')]) 205 # Update charno 206 charno = m.end() 207 # Add any remaining post-example text. 208 output.append(s[charno:]) 209 210 return self.PREFIX + ''.join(output) + self.SUFFIX
    211
    212 - def subfunc(self, match):
    213 other, text = match.group(1, 2) 214 #print 'M %20r %20r' % (other, text) # <- for debugging 215 if other: 216 other = '\n'.join([self.markup(line, 'other') 217 for line in other.split('\n')]) 218 219 if match.group('PROMPT1'): 220 return other + self.markup(text, 'prompt') 221 elif match.group('PROMPT2'): 222 return other + self.markup(text, 'more') 223 elif match.group('KEYWORD'): 224 return other + self.markup(text, 'keyword') 225 elif match.group('BUILTIN'): 226 return other + self.markup(text, 'builtin') 227 elif match.group('COMMENT'): 228 return other + self.markup(text, 'comment') 229 elif match.group('STRING') and '\n' not in text: 230 return other + self.markup(text, 'string') 231 elif match.group('STRING'): 232 # It's a multiline string; colorize the string & prompt 233 # portion of each line. 234 pieces = [] 235 for line in text.split('\n'): 236 if self.PROMPT2_RE.match(line): 237 if len(line) > 4: 238 pieces.append(self.markup(line[:4], 'more') + 239 self.markup(line[4:], 'string')) 240 else: 241 pieces.append(self.markup(line[:4], 'more')) 242 elif line: 243 pieces.append(self.markup(line, 'string')) 244 else: 245 pieces.append('') 246 return other + '\n'.join(pieces) 247 elif match.group('DEFINE'): 248 m = re.match('(?P<def>\w+)(?P<space>\s+)(?P<name>\w+)', text) 249 return other + (self.markup(m.group('def'), 'keyword') + 250 self.markup(m.group('space'), 'other') + 251 self.markup(m.group('name'), 'defname')) 252 elif match.group('EOS') is not None: 253 return other 254 else: 255 assert 0, 'Unexpected match!'
    256
    257 - def markup(self, s, tag):
    258 """ 259 Apply syntax highlighting to a single substring from a doctest 260 block. C{s} is the substring, and C{tag} is the tag that 261 should be applied to the substring. C{tag} will be one of the 262 following strings: 263 264 - C{prompt} -- the Python PS1 prompt (>>>) 265 - C{more} -- the Python PS2 prompt (...) 266 - C{keyword} -- a Python keyword (for, if, etc.) 267 - C{builtin} -- a Python builtin name (abs, dir, etc.) 268 - C{string} -- a string literal 269 - C{comment} -- a comment 270 - C{except} -- an exception traceback (up to the next >>>) 271 - C{output} -- the output from a doctest block. 272 - C{defname} -- the name of a function or class defined by 273 a C{def} or C{class} statement. 274 - C{other} -- anything else (does *not* include output.) 275 """ 276 raise AssertionError("Abstract method")
    277
    278 -class XMLDoctestColorizer(DoctestColorizer):
    279 """ 280 A subclass of DoctestColorizer that generates XML-like output. 281 This class is mainly intended to be used for testing purposes. 282 """ 283 PREFIX = '<colorized>\n' 284 SUFFIX = '</colorized>\n'
    285 - def markup(self, s, tag):
    286 s = s.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;') 287 if tag == 'other': return s 288 else: return '<%s>%s</%s>' % (tag, s, tag)
    289
    290 -class HTMLDoctestColorizer(DoctestColorizer):
    291 """A subclass of DoctestColorizer that generates HTML output.""" 292 PREFIX = '<pre class="py-doctest">\n' 293 SUFFIX = '</pre>\n'
    294 - def markup(self, s, tag):
    295 if tag == 'other': 296 return plaintext_to_html(s) 297 else: 298 return ('<span class="py-%s">%s</span>' % 299 (tag, plaintext_to_html(s)))
    300
    301 -class LaTeXDoctestColorizer(DoctestColorizer):
    302 """A subclass of DoctestColorizer that generates LaTeX output.""" 303 PREFIX = '\\begin{alltt}\n' 304 SUFFIX = '\\end{alltt}\n'
    305 - def markup(self, s, tag):
    306 if tag == 'other': 307 return plaintext_to_latex(s) 308 else: 309 return '\\pysrc%s{%s}' % (tag, plaintext_to_latex(s))
    310

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph.DotGraphUmlModuleNode-class.html0000644000175000017500000007775710750103050030756 0ustar pronovicpronovic epydoc.docwriter.dotgraph.DotGraphUmlModuleNode
    Package epydoc :: Package docwriter :: Module dotgraph :: Class DotGraphUmlModuleNode
    [hide private]
    [frames] | no frames]

    Class DotGraphUmlModuleNode

    source code


    A specialized dot grah node used to display ModuleDocs using UML notation. Simple module nodes look like:

    .----.
    +------------+
    | modulename |
    +------------+
    

    Packages nodes are drawn with their modules & subpackages nested inside:

    .----.
    +----------------------------------------+
    | packagename                            |
    |                                        |
    |  .----.       .----.       .----.      |
    |  +---------+  +---------+  +---------+ |
    |  | module1 |  | module2 |  | module3 | |
    |  +---------+  +---------+  +---------+ |
    |                                        |
    +----------------------------------------+
    
    Instance Methods [hide private]
     
    __init__(self, module_doc, linker, context, collapsed=False, excluded_submodules=(), **options) source code
    call graph 
     
    _get_html_label(self, package)
    Returns: (label, depth, width) where:
    source code
    call graph 
     
    _color(self, package, depth) source code
    call graph 
     
    to_dotfile(self)
    Return the dot commands that should be used to render this node.
    source code
    call graph 

    Inherited from DotGraphNode: __getitem__, __setitem__

    Class Variables [hide private]
      _MODULE_LABEL = ' \n <TABLE BORDER="0" CELLBORDER="0" CELLS...
    Expects: (color, color, url, tooltip, body)
      _NESTED_BODY = '\n <TABLE BORDER="0" CELLBORDER="0" CELLPAD...
    Expects: (name, body_rows)
      _NESTED_BODY_ROW = '\n <TR><TD>\n <TABLE BORDER="0" CE...
    Expects: (cells,)
      _COLOR_DIFF = 24

    Inherited from DotGraphNode (private): _next_id

    Method Details [hide private]

    __init__(self, module_doc, linker, context, collapsed=False, excluded_submodules=(), **options)
    (Constructor)

    source code 
    call graph 
    Overrides: DotGraphNode.__init__

    _get_html_label(self, package)

    source code 
    call graph 
    Returns:

    (label, depth, width) where:

    • label is the HTML label
    • depth is the depth of the package tree (for coloring)
    • width is the max width of the HTML label, roughly in units of characters.

    to_dotfile(self)

    source code 
    call graph 
    Return the dot commands that should be used to render this node.
    Overrides: DotGraphNode.to_dotfile
    (inherited documentation)

    Class Variable Details [hide private]

    _MODULE_LABEL

    Expects: (color, color, url, tooltip, body)
    Value:
    ''' 
        <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" ALIGN="LEFT">
        <TR><TD ALIGN="LEFT" VALIGN="BOTTOM" HEIGHT="8" WIDTH="16"
                FIXEDSIZE="true" BGCOLOR="%s" BORDER="1" PORT="tab"></TD><\
    /TR>
        <TR><TD ALIGN="LEFT" VALIGN="TOP" BGCOLOR="%s" BORDER="1" WIDTH="2\
    0"
                PORT="body" HREF="%s" TOOLTIP="%s">%s</TD></TR>
    ...
    

    _NESTED_BODY

    Expects: (name, body_rows)
    Value:
    '''
        <TABLE BORDER="0" CELLBORDER="0" CELLPADDING="0" CELLSPACING="0">
        <TR><TD ALIGN="LEFT">%s</TD></TR>
        %s
        </TABLE>'''
    

    _NESTED_BODY_ROW

    Expects: (cells,)
    Value:
    '''
        <TR><TD>
          <TABLE BORDER="0" CELLBORDER="0"><TR>%s</TR></TABLE>
        </TD></TR>'''
    

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter-module.html0000644000175000017500000000171310750103050023724 0ustar pronovicpronovic docwriter

    Module docwriter



    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.util.RunSubprocessError-class.html0000644000175000017500000002157310750103050025570 0ustar pronovicpronovic epydoc.util.RunSubprocessError
    Package epydoc :: Module util :: Class RunSubprocessError
    [hide private]
    [frames] | no frames]

    Class RunSubprocessError

    source code


    Instance Methods [hide private]
     
    __init__(self, cmd, out, err) source code

    Inherited from exceptions.EnvironmentError: __str__

    Inherited from exceptions.Exception: __getitem__

    Method Details [hide private]

    __init__(self, cmd, out, err)
    (Constructor)

    source code 
    Overrides: exceptions.Exception.__init__

    epydoc-3.0.1+dfsg/doc/api/epydoc.compat-module.html0000644000175000017500000001534510750103050022430 0ustar pronovicpronovic epydoc.compat
    Package epydoc :: Module compat
    [hide private]
    [frames] | no frames]

    Module compat

    source code

    Backwards compatibility with previous versions of Python.

    This module provides backwards compatibility by defining several functions and classes that were not available in earlier versions of Python. Intented usage:

    >>> from epydoc.compat import *

    Currently, epydoc requires Python 2.3+.

    Functions [hide private]
     
    sorted(iterable, cmp=None, key=None, reverse=False) source code
     
    reversed(iterable) source code
    epydoc-3.0.1+dfsg/doc/api/epydoc.docbuilder._ProgressEstimator-class.html0000644000175000017500000003075510750103050026735 0ustar pronovicpronovic epydoc.docbuilder._ProgressEstimator
    Package epydoc :: Module docbuilder :: Class _ProgressEstimator
    [hide private]
    [frames] | no frames]

    Class _ProgressEstimator

    source code

    Used to keep track of progress when generating the initial docs for the given items. (It is not known in advance how many items a package directory will contain, since it might depend on those packages' __path__ values.)

    Instance Methods [hide private]
     
    __init__(self, items) source code
    call graph 
     
    progress(self) source code
    call graph 
     
    revise_estimate(self, pkg_item, modules, subpackages) source code
    call graph 
     
    _est_pkg_modules(self, package_dir) source code
    call graph 
    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.VariableDoc-class.html0000644000175000017500000014434110750103050024375 0ustar pronovicpronovic epydoc.apidoc.VariableDoc
    Package epydoc :: Module apidoc :: Class VariableDoc
    [hide private]
    [frames] | no frames]

    Class VariableDoc

    source code


    API documentation information about a single Python variable.


    Note: The only time a VariableDoc will have its own docstring is if that variable was created using an assignment statement, and that assignment statement had a docstring-comment or was followed by a pseudo-docstring.

    Instance Methods [hide private]
     
    __init__(self, **kwargs)
    Construct a new APIDoc object.
    source code
    call graph 
     
    __repr__(self)
    repr(x)
    source code
     
    _get_defining_module(self) source code
    call graph 
     
    apidoc_links(self, **filters)
    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
    source code
    call graph 
    bool
    is_detailed(self)
    Does this object deserve a box with extra details?
    source code
    call graph 

    Inherited from APIDoc: __cmp__, __hash__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

    Instance Variables [hide private]
        Basic Variable Information
    str name = _Sentinel('UNKNOWN')
    The name of this variable in its containing namespace.
    ValueDoc container = _Sentinel('UNKNOWN')
    API documentation for the namespace that contains this variable.
    DottedName canonical_name = _Sentinel('UNKNOWN')
    A dotted name that serves as a unique identifier for this VariableDoc.
    ValueDoc value = _Sentinel('UNKNOWN')
    The API documentation for this variable's value.
        Information Extracted from Docstrings
    ParsedDocstring type_descr = _Sentinel('UNKNOWN')
    A description of the variable's expected type, extracted from its docstring.

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Information about Imported Variables
    DottedName imported_from = _Sentinel('UNKNOWN')
    The fully qualified dotted name of the variable that this variable's value was imported from.
    bool is_imported = _Sentinel('UNKNOWN')
    Was this variable's value imported from another module? (Exception: variables that are explicitly included in __all__ have is_imported set to False, even if they are in fact imported.)
        Information about Variables in Classes
    bool is_instvar = _Sentinel('UNKNOWN')
    If true, then this variable is an instance variable; if false, then this variable is a class variable.
    VariableDoc overrides = _Sentinel('UNKNOWN')
    The API documentation for the variable that is overridden by this variable.
        Flags
    bool is_alias = _Sentinel('UNKNOWN')
    Is this variable an alias for another variable with the same value? If so, then this variable will be dispreferred when assigning canonical names.
    bool is_public = _Sentinel('UNKNOWN')
    Is this variable part of its container's public API?
        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]
      defining_module
    A read-only property that can be used to get the variable's defining module.

    Inherited from object: __class__

    Method Details [hide private]

    __init__(self, **kwargs)
    (Constructor)

    source code 
    call graph 

    Construct a new APIDoc object. Keyword arguments may be used to initialize the new APIDoc's attributes.

    Raises:
    • TypeError - If a keyword argument is specified that does not correspond to a valid attribute for this (sub)class of APIDoc.
    Overrides: object.__init__
    (inherited documentation)

    __repr__(self)
    (Representation operator)

    source code 
    repr(x)
    
    
    Overrides: object.__repr__
    (inherited documentation)

    apidoc_links(self, **filters)

    source code 
    call graph 

    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

    Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

    • imports: Imported variables.
    • packages: Containing packages for modules.
    • submodules: Contained submodules for packages.
    • bases: Bases for classes.
    • subclasses: Subclasses for classes.
    • variables: All variables.
    • private: Private variables.
    • overrides: Points from class variables to the variables they override. This filter is False by default.
    Overrides: APIDoc.apidoc_links
    (inherited documentation)

    is_detailed(self)

    source code 
    call graph 

    Does this object deserve a box with extra details?

    Returns: bool
    True if the object needs extra details, else False.
    Overrides: APIDoc.is_detailed
    (inherited documentation)

    Instance Variable Details [hide private]

    canonical_name

    A dotted name that serves as a unique identifier for this VariableDoc. It should be formed by concatenating the VariableDoc's container with its name.
    Type:
    DottedName
    Value:
    _Sentinel('UNKNOWN')
    

    imported_from

    The fully qualified dotted name of the variable that this variable's value was imported from. This attribute should only be defined if is_instvar is true.
    Type:
    DottedName
    Value:
    _Sentinel('UNKNOWN')
    

    is_instvar

    If true, then this variable is an instance variable; if false, then this variable is a class variable. This attribute should only be defined if the containing namespace is a class
    Type:
    bool
    Value:
    _Sentinel('UNKNOWN')
    

    overrides

    The API documentation for the variable that is overridden by this variable. This attribute should only be defined if the containing namespace is a class.
    Type:
    VariableDoc
    Value:
    _Sentinel('UNKNOWN')
    

    Property Details [hide private]

    defining_module

    A read-only property that can be used to get the variable's defining module. This is defined as the defining module of the variable's container.

    Get Method:
    _get_defining_module(self)

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.log-module.html0000644000175000017500000000613410750103050022505 0ustar pronovicpronovic log

    Module log


    Classes

    Logger
    SimpleLogger

    Functions

    close
    debug
    docstring_warning
    end_block
    end_progress
    error
    fatal
    info
    progress
    register_logger
    remove_logger
    start_block
    start_progress
    warning

    Variables

    DEBUG
    DOCSTRING_WARNING
    ERROR
    FATAL
    INFO
    WARNING

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.plaintext.ParsedPlaintextDocstring-class.html0000644000175000017500000007115010750103050031252 0ustar pronovicpronovic epydoc.markup.plaintext.ParsedPlaintextDocstring
    Package epydoc :: Package markup :: Module plaintext :: Class ParsedPlaintextDocstring
    [hide private]
    [frames] | no frames]

    Class ParsedPlaintextDocstring

    source code


    Instance Methods [hide private]
     
    __init__(self, text, **options) source code
    call graph 
    string
    to_html(self, docstring_linker, **options)
    Translate this docstring to HTML.
    source code
    call graph 
    string
    to_latex(self, docstring_linker, **options)
    Translate this docstring to LaTeX.
    source code
    string
    to_plaintext(self, docstring_linker, **options)
    Translate this docstring to plaintext.
    source code
    call graph 
    (ParsedDocstring, bool)
    summary(self)
    Returns: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary.
    source code
    call graph 

    Inherited from ParsedDocstring: __add__, concatenate, index_terms, split_fields

    Class Variables [hide private]
      _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?(?:\.(\s|$)|\n[\t ]*\n))')
    Method Details [hide private]

    to_html(self, docstring_linker, **options)

    source code 
    call graph 

    Translate this docstring to HTML.

    Parameters:
    • docstring_linker - An HTML translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    An HTML fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_html
    (inherited documentation)

    to_latex(self, docstring_linker, **options)

    source code 

    Translate this docstring to LaTeX.

    Parameters:
    • docstring_linker - A LaTeX translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A LaTeX fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_latex
    (inherited documentation)

    to_plaintext(self, docstring_linker, **options)

    source code 
    call graph 

    Translate this docstring to plaintext.

    Parameters:
    • docstring_linker - A plaintext translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A plaintext fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_plaintext
    (inherited documentation)

    summary(self)

    source code 
    call graph 
    Returns: (ParsedDocstring, bool)
    A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring.
    Overrides: ParsedDocstring.summary
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.compat-module.html0000644000175000017500000000223210750103050023202 0ustar pronovicpronovic compat

    Module compat


    Functions

    reversed
    sorted

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.StructuringError-class.html0000644000175000017500000002327210750103050027325 0ustar pronovicpronovic epydoc.markup.epytext.StructuringError
    Package epydoc :: Package markup :: Module epytext :: Class StructuringError
    [hide private]
    [frames] | no frames]

    Class StructuringError

    source code


    An error generated while structuring a formatted documentation string.

    Instance Methods [hide private]

    Inherited from ParseError: __cmp__, __init__, __repr__, __str__, descr, is_fatal, linenum, set_linenum_offset

    Inherited from exceptions.Exception: __getitem__

    Instance Variables [hide private]

    Inherited from ParseError (private): _descr, _fatal, _linenum, _offset

    epydoc-3.0.1+dfsg/doc/api/epydoc.docintrospecter-pysrc.html0000644000175000017500000123666710750103050024244 0ustar pronovicpronovic epydoc.docintrospecter
    Package epydoc :: Module docintrospecter
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docintrospecter

       1  # epydoc -- Introspection 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: docintrospecter.py 1678 2008-01-29 17:21:29Z edloper $ 
       8   
       9  """ 
      10  Extract API documentation about python objects by directly introspecting 
      11  their values. 
      12   
      13  The function L{introspect_docs()}, which provides the main interface 
      14  of this module, examines a Python objects via introspection, and uses 
      15  the information it finds to create an L{APIDoc} objects containing the 
      16  API documentation for that objects. 
      17   
      18  The L{register_introspecter()} method can be used to extend the 
      19  functionality of C{docintrospector}, by providing methods that handle 
      20  special value types. 
      21  """ 
      22  __docformat__ = 'epytext en' 
      23   
      24  ###################################################################### 
      25  ## Imports 
      26  ###################################################################### 
      27   
      28  import inspect, re, sys, os.path, imp 
      29  # API documentation encoding: 
      30  from epydoc.apidoc import * 
      31  # Type comparisons: 
      32  from types import * 
      33  # Error reporting: 
      34  from epydoc import log 
      35  # Helper functions: 
      36  from epydoc.util import * 
      37  # For extracting encoding for docstrings: 
      38  import epydoc.docparser 
      39  # Builtin values 
      40  import __builtin__ 
      41  # Backwards compatibility 
      42  from epydoc.compat import *  
      43   
      44  ###################################################################### 
      45  ## Caches 
      46  ###################################################################### 
      47   
      48  _valuedoc_cache = {} 
      49  """A cache containing the API documentation for values that we've 
      50  already seen.  This cache is implemented as a dictionary that maps a 
      51  value's pyid to its L{ValueDoc}. 
      52   
      53  Note that if we encounter a value but decide not to introspect it 
      54  (because it's imported from another module), then C{_valuedoc_cache} 
      55  will contain an entry for the value, but the value will not be listed 
      56  in L{_introspected_values}.""" 
      57   
      58  _introspected_values = {} 
      59  """A record which values we've introspected, encoded as a dictionary from 
      60  pyid to C{bool}.""" 
      61   
    
    62 -def clear_cache():
    63 """ 64 Discard any cached C{APIDoc} values that have been computed for 65 introspected values. 66 """ 67 _valuedoc_cache.clear() 68 _introspected_values.clear()
    69 70 ###################################################################### 71 ## Introspection 72 ###################################################################### 73
    74 -def introspect_docs(value=None, name=None, filename=None, context=None, 75 is_script=False, module_name=None):
    76 """ 77 Generate the API documentation for a specified object by 78 introspecting Python values, and return it as a L{ValueDoc}. The 79 object to generate documentation for may be specified using 80 the C{value} parameter, the C{filename} parameter, I{or} the 81 C{name} parameter. (It is an error to specify more than one 82 of these three parameters, or to not specify any of them.) 83 84 @param value: The python object that should be documented. 85 @param filename: The name of the file that contains the python 86 source code for a package, module, or script. If 87 C{filename} is specified, then C{introspect} will return a 88 C{ModuleDoc} describing its contents. 89 @param name: The fully-qualified python dotted name of any 90 value (including packages, modules, classes, and 91 functions). C{DocParser} will automatically figure out 92 which module(s) it needs to import in order to find the 93 documentation for the specified object. 94 @param context: The API documentation for the class of module 95 that contains C{value} (if available). 96 @param module_name: The name of the module where the value is defined. 97 Useful to retrieve the docstring encoding if there is no way to 98 detect the module by introspection (such as in properties) 99 """ 100 if value is None and name is not None and filename is None: 101 value = get_value_from_name(DottedName(name)) 102 elif value is None and name is None and filename is not None: 103 if is_script: 104 value = get_value_from_scriptname(filename) 105 else: 106 value = get_value_from_filename(filename, context) 107 elif name is None and filename is None: 108 # it's ok if value is None -- that's a value, after all. 109 pass 110 else: 111 raise ValueError("Expected exactly one of the following " 112 "arguments: value, name, filename") 113 114 pyid = id(value) 115 116 # If we've already introspected this value, then simply return 117 # its ValueDoc from our cache. 118 if pyid in _introspected_values: 119 # If the file is a script, then adjust its name. 120 if is_script and filename is not None: 121 _valuedoc_cache[pyid].canonical_name = DottedName( 122 munge_script_name(str(filename))) 123 return _valuedoc_cache[pyid] 124 125 # Create an initial value doc for this value & add it to the cache. 126 val_doc = _get_valuedoc(value) 127 128 # Introspect the value. 129 _introspected_values[pyid] = True 130 introspect_func = _get_introspecter(value) 131 introspect_func(value, val_doc, module_name=module_name) 132 133 # Set canonical name, if it was given 134 if val_doc.canonical_name is UNKNOWN and name is not None: 135 val_doc.canonical_name = DottedName(name) 136 137 # If the file is a script, then adjust its name. 138 if is_script and filename is not None: 139 val_doc.canonical_name = DottedName(munge_script_name(str(filename))) 140 141 if val_doc.canonical_name is UNKNOWN and filename is not None: 142 shadowed_name = DottedName(value.__name__) 143 log.warning("Module %s is shadowed by a variable with " 144 "the same name." % shadowed_name) 145 val_doc.canonical_name = DottedName(str(shadowed_name)+"'") 146 147 return val_doc
    148
    149 -def _get_valuedoc(value):
    150 """ 151 If a C{ValueDoc} for the given value exists in the valuedoc 152 cache, then return it; otherwise, create a new C{ValueDoc}, 153 add it to the cache, and return it. When possible, the new 154 C{ValueDoc}'s C{pyval}, C{repr}, and C{canonical_name} 155 attributes will be set appropriately. 156 """ 157 pyid = id(value) 158 val_doc = _valuedoc_cache.get(pyid) 159 if val_doc is None: 160 try: canonical_name = get_canonical_name(value, strict=True) 161 except DottedName.InvalidDottedName: canonical_name = UNKNOWN 162 val_doc = ValueDoc(pyval=value, canonical_name = canonical_name, 163 docs_extracted_by='introspecter') 164 _valuedoc_cache[pyid] = val_doc 165 166 # If it's a module, then do some preliminary introspection. 167 # Otherwise, check what the containing module is (used e.g. 168 # to decide what markup language should be used for docstrings) 169 if inspect.ismodule(value): 170 introspect_module(value, val_doc, preliminary=True) 171 val_doc.defining_module = val_doc 172 else: 173 module_name = str(get_containing_module(value)) 174 module = sys.modules.get(module_name) 175 if module is not None and inspect.ismodule(module): 176 val_doc.defining_module = _get_valuedoc(module) 177 178 return val_doc
    179 180 #//////////////////////////////////////////////////////////// 181 # Module Introspection 182 #//////////////////////////////////////////////////////////// 183 184 #: A list of module variables that should not be included in a 185 #: module's API documentation. 186 UNDOCUMENTED_MODULE_VARS = ( 187 '__builtins__', '__doc__', '__all__', '__file__', '__path__', 188 '__name__', '__extra_epydoc_fields__', '__docformat__') 189
    190 -def introspect_module(module, module_doc, module_name=None, preliminary=False):
    191 """ 192 Add API documentation information about the module C{module} 193 to C{module_doc}. 194 """ 195 module_doc.specialize_to(ModuleDoc) 196 197 # Record the module's docformat 198 if hasattr(module, '__docformat__'): 199 module_doc.docformat = unicode(module.__docformat__) 200 201 # Record the module's filename 202 if hasattr(module, '__file__'): 203 try: module_doc.filename = unicode(module.__file__) 204 except KeyboardInterrupt: raise 205 except: pass 206 if module_doc.filename is not UNKNOWN: 207 try: module_doc.filename = py_src_filename(module_doc.filename) 208 except ValueError: pass 209 210 # If this is just a preliminary introspection, then don't do 211 # anything else. (Typically this is true if this module was 212 # imported, but is not included in the set of modules we're 213 # documenting.) 214 module_doc.variables = {} 215 if preliminary: return 216 217 # Record the module's docstring 218 if hasattr(module, '__doc__'): 219 module_doc.docstring = get_docstring(module) 220 221 # If the module has a __path__, then it's (probably) a 222 # package; so set is_package=True and record its __path__. 223 if hasattr(module, '__path__'): 224 module_doc.is_package = True 225 try: module_doc.path = [unicode(p) for p in module.__path__] 226 except KeyboardInterrupt: raise 227 except: pass 228 else: 229 module_doc.is_package = False 230 231 # Make sure we have a name for the package. 232 dotted_name = module_doc.canonical_name 233 if dotted_name is UNKNOWN: 234 dotted_name = DottedName(module.__name__) 235 name_without_primes = DottedName(str(dotted_name).replace("'", "")) 236 237 # Record the module's parent package, if it has one. 238 if len(dotted_name) > 1: 239 package_name = str(dotted_name.container()) 240 package = sys.modules.get(package_name) 241 if package is not None: 242 module_doc.package = introspect_docs(package) 243 else: 244 module_doc.package = None 245 246 # Initialize the submodules property 247 module_doc.submodules = [] 248 249 # Add the module to its parent package's submodules list. 250 if module_doc.package not in (None, UNKNOWN): 251 module_doc.package.submodules.append(module_doc) 252 253 # Look up the module's __all__ attribute (public names). 254 public_names = None 255 if hasattr(module, '__all__'): 256 try: 257 public_names = set([str(name) for name in module.__all__]) 258 except KeyboardInterrupt: raise 259 except: pass 260 261 # Record the module's variables. 262 module_doc.variables = {} 263 for child_name in dir(module): 264 if child_name in UNDOCUMENTED_MODULE_VARS: continue 265 child = getattr(module, child_name) 266 267 # Create a VariableDoc for the child, and introspect its 268 # value if it's defined in this module. 269 container = get_containing_module(child) 270 if ((container is not None and 271 container == name_without_primes) or 272 (public_names is not None and 273 child_name in public_names)): 274 # Local variable. 275 child_val_doc = introspect_docs(child, context=module_doc, 276 module_name=dotted_name) 277 child_var_doc = VariableDoc(name=child_name, 278 value=child_val_doc, 279 is_imported=False, 280 container=module_doc, 281 docs_extracted_by='introspecter') 282 elif container is None or module_doc.canonical_name is UNKNOWN: 283 284 # Don't introspect stuff "from __future__" 285 if is_future_feature(child): continue 286 287 # Possibly imported variable. 288 child_val_doc = introspect_docs(child, context=module_doc) 289 child_var_doc = VariableDoc(name=child_name, 290 value=child_val_doc, 291 container=module_doc, 292 docs_extracted_by='introspecter') 293 else: 294 # Imported variable. 295 child_val_doc = _get_valuedoc(child) 296 child_var_doc = VariableDoc(name=child_name, 297 value=child_val_doc, 298 is_imported=True, 299 container=module_doc, 300 docs_extracted_by='introspecter') 301 302 # If the module's __all__ attribute is set, use it to set the 303 # variables public/private status and imported status. 304 if public_names is not None: 305 if child_name in public_names: 306 child_var_doc.is_public = True 307 if not isinstance(child_var_doc, ModuleDoc): 308 child_var_doc.is_imported = False 309 else: 310 child_var_doc.is_public = False 311 312 module_doc.variables[child_name] = child_var_doc 313 314 return module_doc
    315 316 #//////////////////////////////////////////////////////////// 317 # Class Introspection 318 #//////////////////////////////////////////////////////////// 319 320 #: A list of class variables that should not be included in a 321 #: class's API documentation. 322 UNDOCUMENTED_CLASS_VARS = ( 323 '__doc__', '__module__', '__dict__', '__weakref__', '__slots__', 324 '__pyx_vtable__') 325
    326 -def introspect_class(cls, class_doc, module_name=None):
    327 """ 328 Add API documentation information about the class C{cls} 329 to C{class_doc}. 330 """ 331 class_doc.specialize_to(ClassDoc) 332 333 # Record the class's docstring. 334 class_doc.docstring = get_docstring(cls) 335 336 # Record the class's __all__ attribute (public names). 337 public_names = None 338 if hasattr(cls, '__all__'): 339 try: 340 public_names = set([str(name) for name in cls.__all__]) 341 except KeyboardInterrupt: raise 342 except: pass 343 344 # Start a list of subclasses. 345 class_doc.subclasses = [] 346 347 # Sometimes users will define a __metaclass__ that copies all 348 # class attributes from bases directly into the derived class's 349 # __dict__ when the class is created. (This saves the lookup time 350 # needed to search the base tree for an attribute.) But for the 351 # docs, we only want to list these copied attributes in the 352 # parent. So only add an attribute if it is not identical to an 353 # attribute of a base class. (Unfortunately, this can sometimes 354 # cause an attribute to look like it was inherited, even though it 355 # wasn't, if it happens to have the exact same value as the 356 # corresponding base's attribute.) An example of a case where 357 # this helps is PyQt -- subclasses of QWidget get about 300 358 # methods injected into them. 359 base_children = {} 360 361 # Record the class's base classes; and add the class to its 362 # base class's subclass lists. 363 if hasattr(cls, '__bases__'): 364 try: bases = list(cls.__bases__) 365 except: 366 bases = None 367 log.warning("Class '%s' defines __bases__, but it does not " 368 "contain an iterable; ignoring base list." 369 % getattr(cls, '__name__', '??')) 370 if bases is not None: 371 class_doc.bases = [] 372 for base in bases: 373 basedoc = introspect_docs(base) 374 class_doc.bases.append(basedoc) 375 basedoc.subclasses.append(class_doc) 376 377 bases.reverse() 378 for base in bases: 379 if hasattr(base, '__dict__'): 380 base_children.update(base.__dict__) 381 382 # The module name is not defined if the class is being introspected 383 # as another class base. 384 if module_name is None and class_doc.defining_module not in (None, UNKNOWN): 385 module_name = class_doc.defining_module.canonical_name 386 387 # Record the class's local variables. 388 class_doc.variables = {} 389 if hasattr(cls, '__dict__'): 390 private_prefix = '_%s__' % getattr(cls, '__name__', '<none>') 391 for child_name, child in cls.__dict__.items(): 392 if (child_name in base_children 393 and base_children[child_name] == child): 394 continue 395 396 if child_name.startswith(private_prefix): 397 child_name = child_name[len(private_prefix)-2:] 398 if child_name in UNDOCUMENTED_CLASS_VARS: continue 399 val_doc = introspect_docs(child, context=class_doc, 400 module_name=module_name) 401 var_doc = VariableDoc(name=child_name, value=val_doc, 402 container=class_doc, 403 docs_extracted_by='introspecter') 404 if public_names is not None: 405 var_doc.is_public = (child_name in public_names) 406 class_doc.variables[child_name] = var_doc 407 408 return class_doc
    409 410 #//////////////////////////////////////////////////////////// 411 # Routine Introspection 412 #//////////////////////////////////////////////////////////// 413
    414 -def introspect_routine(routine, routine_doc, module_name=None):
    415 """Add API documentation information about the function 416 C{routine} to C{routine_doc} (specializing it to C{Routine_doc}).""" 417 routine_doc.specialize_to(RoutineDoc) 418 419 # Extract the underying function 420 if isinstance(routine, MethodType): 421 func = routine.im_func 422 elif isinstance(routine, staticmethod): 423 func = routine.__get__(0) 424 elif isinstance(routine, classmethod): 425 func = routine.__get__(0).im_func 426 else: 427 func = routine 428 429 # Record the function's docstring. 430 routine_doc.docstring = get_docstring(func) 431 432 # Record the function's signature. 433 if isinstance(func, FunctionType): 434 (args, vararg, kwarg, defaults) = inspect.getargspec(func) 435 436 # Add the arguments. 437 routine_doc.posargs = args 438 routine_doc.vararg = vararg 439 routine_doc.kwarg = kwarg 440 441 # Set default values for positional arguments. 442 routine_doc.posarg_defaults = [None]*len(args) 443 if defaults is not None: 444 offset = len(args)-len(defaults) 445 for i in range(len(defaults)): 446 default_val = introspect_docs(defaults[i]) 447 routine_doc.posarg_defaults[i+offset] = default_val 448 449 # If it's a bound method, then strip off the first argument. 450 if isinstance(routine, MethodType) and routine.im_self is not None: 451 routine_doc.posargs = routine_doc.posargs[1:] 452 routine_doc.posarg_defaults = routine_doc.posarg_defaults[1:] 453 454 # Set the routine's line number. 455 if hasattr(func, 'func_code'): 456 routine_doc.lineno = func.func_code.co_firstlineno 457 458 else: 459 # [XX] I should probably use UNKNOWN here?? 460 # dvarrazzo: if '...' is to be changed, also check that 461 # `docstringparser.process_arg_field()` works correctly. 462 # See SF bug #1556024. 463 routine_doc.posargs = ['...'] 464 routine_doc.posarg_defaults = [None] 465 routine_doc.kwarg = None 466 routine_doc.vararg = None 467 468 # Change type, if appropriate. 469 if isinstance(routine, staticmethod): 470 routine_doc.specialize_to(StaticMethodDoc) 471 if isinstance(routine, classmethod): 472 routine_doc.specialize_to(ClassMethodDoc) 473 474 return routine_doc
    475 476 #//////////////////////////////////////////////////////////// 477 # Property Introspection 478 #//////////////////////////////////////////////////////////// 479
    480 -def introspect_property(prop, prop_doc, module_name=None):
    481 """Add API documentation information about the property 482 C{prop} to C{prop_doc} (specializing it to C{PropertyDoc}).""" 483 prop_doc.specialize_to(PropertyDoc) 484 485 # Record the property's docstring. 486 prop_doc.docstring = get_docstring(prop, module_name=module_name) 487 488 # Record the property's access functions. 489 if hasattr(prop, 'fget'): 490 prop_doc.fget = introspect_docs(prop.fget) 491 prop_doc.fset = introspect_docs(prop.fset) 492 prop_doc.fdel = introspect_docs(prop.fdel) 493 494 return prop_doc
    495 496 #//////////////////////////////////////////////////////////// 497 # Generic Value Introspection 498 #//////////////////////////////////////////////////////////// 499
    500 -def introspect_other(val, val_doc, module_name=None):
    501 """Specialize val_doc to a C{GenericValueDoc} and return it.""" 502 val_doc.specialize_to(GenericValueDoc) 503 return val_doc
    504 505 #//////////////////////////////////////////////////////////// 506 # Helper functions 507 #//////////////////////////////////////////////////////////// 508
    509 -def isclass(object):
    510 """ 511 Return true if the given object is a class. In particular, return 512 true if object is an instance of C{types.TypeType} or of 513 C{types.ClassType}. This is used instead of C{inspect.isclass()}, 514 because the latter returns true for objects that are not classes 515 (in particular, it returns true for any object that has a 516 C{__bases__} attribute, including objects that define 517 C{__getattr__} to always return a value). 518 """ 519 return isinstance(object, tuple(_CLASS_TYPES))
    520 521 _CLASS_TYPES = set([TypeType, ClassType]) 522 """A list of types that should be treated as classes.""" 523
    524 -def register_class_type(typ):
    525 """Add a type to the lists of types that should be treated as 526 classes. By default, this list contains C{TypeType} and 527 C{ClassType}.""" 528 _CLASS_TYPES.add(typ)
    529 530 __future_check_works = None 531
    532 -def is_future_feature(object):
    533 """ 534 Return True if C{object} results from a C{from __future__ import feature} 535 statement. 536 """ 537 # Guard from unexpected implementation changes of the __future__ module. 538 global __future_check_works 539 if __future_check_works is not None: 540 if __future_check_works: 541 import __future__ 542 return isinstance(object, __future__._Feature) 543 else: 544 return False 545 else: 546 __future_check_works = True 547 try: 548 return is_future_feature(object) 549 except: 550 __future_check_works = False 551 log.warning("Troubles inspecting __future__. Python implementation" 552 " may have been changed.") 553 return False
    554
    555 -def get_docstring(value, module_name=None):
    556 """ 557 Return the docstring for the given value; or C{None} if it 558 does not have a docstring. 559 @rtype: C{unicode} 560 """ 561 docstring = getattr(value, '__doc__', None) 562 if docstring is None: 563 return None 564 elif isinstance(docstring, unicode): 565 return docstring 566 elif isinstance(docstring, str): 567 try: return unicode(docstring, 'ascii') 568 except UnicodeDecodeError: 569 if module_name is None: 570 module_name = get_containing_module(value) 571 if module_name is not None: 572 try: 573 module = get_value_from_name(module_name) 574 filename = py_src_filename(module.__file__) 575 encoding = epydoc.docparser.get_module_encoding(filename) 576 return unicode(docstring, encoding) 577 except KeyboardInterrupt: raise 578 except Exception: pass 579 if hasattr(value, '__name__'): name = value.__name__ 580 else: name = repr(value) 581 log.warning("%s's docstring is not a unicode string, but it " 582 "contains non-ascii data -- treating it as " 583 "latin-1." % name) 584 return unicode(docstring, 'latin-1') 585 return None 586 elif value is BuiltinMethodType: 587 # Don't issue a warning for this special case. 588 return None 589 else: 590 if hasattr(value, '__name__'): name = value.__name__ 591 else: name = repr(value) 592 log.warning("%s's docstring is not a string -- ignoring it." % 593 name) 594 return None
    595
    596 -def get_canonical_name(value, strict=False):
    597 """ 598 @return: the canonical name for C{value}, or C{UNKNOWN} if no 599 canonical name can be found. Currently, C{get_canonical_name} 600 can find canonical names for: modules; functions; non-nested 601 classes; methods of non-nested classes; and some class methods 602 of non-nested classes. 603 604 @rtype: L{DottedName} or C{UNKNOWN} 605 """ 606 if not hasattr(value, '__name__'): return UNKNOWN 607 608 # Get the name via introspection. 609 if isinstance(value, ModuleType): 610 try: 611 dotted_name = DottedName(value.__name__, strict=strict) 612 # If the module is shadowed by a variable in its parent 613 # package(s), then add a prime mark to the end, to 614 # differentiate it from the variable that shadows it. 615 if verify_name(value, dotted_name) is UNKNOWN: 616 log.warning("Module %s is shadowed by a variable with " 617 "the same name." % dotted_name) 618 # Note -- this return bypasses verify_name check: 619 return DottedName(value.__name__+"'") 620 except DottedName.InvalidDottedName: 621 # Name is not a valid Python identifier -- treat as script. 622 if hasattr(value, '__file__'): 623 filename = '%s' % value.__str__ 624 dotted_name = DottedName(munge_script_name(filename)) 625 626 elif isclass(value): 627 if value.__module__ == '__builtin__': 628 dotted_name = DottedName(value.__name__, strict=strict) 629 else: 630 dotted_name = DottedName(value.__module__, value.__name__, 631 strict=strict) 632 633 elif (inspect.ismethod(value) and value.im_self is not None and 634 value.im_class is ClassType and 635 not value.__name__.startswith('<')): # class method. 636 class_name = get_canonical_name(value.im_self) 637 if class_name is UNKNOWN: return UNKNOWN 638 dotted_name = DottedName(class_name, value.__name__, strict=strict) 639 elif (inspect.ismethod(value) and 640 not value.__name__.startswith('<')): 641 class_name = get_canonical_name(value.im_class) 642 if class_name is UNKNOWN: return UNKNOWN 643 dotted_name = DottedName(class_name, value.__name__, strict=strict) 644 elif (isinstance(value, FunctionType) and 645 not value.__name__.startswith('<')): 646 module_name = _find_function_module(value) 647 if module_name is None: return UNKNOWN 648 dotted_name = DottedName(module_name, value.__name__, strict=strict) 649 else: 650 return UNKNOWN 651 652 return verify_name(value, dotted_name)
    653
    654 -def verify_name(value, dotted_name):
    655 """ 656 Verify the name. E.g., if it's a nested class, then we won't be 657 able to find it with the name we constructed. 658 """ 659 if dotted_name is UNKNOWN: return UNKNOWN 660 if len(dotted_name) == 1 and hasattr(__builtin__, dotted_name[0]): 661 return dotted_name 662 named_value = sys.modules.get(dotted_name[0]) 663 if named_value is None: return UNKNOWN 664 for identifier in dotted_name[1:]: 665 try: named_value = getattr(named_value, identifier) 666 except: return UNKNOWN 667 if value is named_value: 668 return dotted_name 669 else: 670 return UNKNOWN
    671 672 # [xx] not used:
    673 -def value_repr(value):
    674 try: 675 s = '%r' % value 676 if isinstance(s, str): 677 s = decode_with_backslashreplace(s) 678 return s 679 except: 680 return UNKNOWN
    681
    682 -def get_containing_module(value):
    683 """ 684 Return the name of the module containing the given value, or 685 C{None} if the module name can't be determined. 686 @rtype: L{DottedName} 687 """ 688 if inspect.ismodule(value): 689 return DottedName(value.__name__) 690 elif isclass(value): 691 return DottedName(value.__module__) 692 elif (inspect.ismethod(value) and value.im_self is not None and 693 value.im_class is ClassType): # class method. 694 return DottedName(value.im_self.__module__) 695 elif inspect.ismethod(value): 696 return DottedName(value.im_class.__module__) 697 elif inspect.isroutine(value): 698 module = _find_function_module(value) 699 if module is None: return None 700 return DottedName(module) 701 else: 702 return None
    703
    704 -def _find_function_module(func):
    705 """ 706 @return: The module that defines the given function. 707 @rtype: C{module} 708 @param func: The function whose module should be found. 709 @type func: C{function} 710 """ 711 if hasattr(func, '__module__'): 712 return func.__module__ 713 try: 714 module = inspect.getmodule(func) 715 if module: return module.__name__ 716 except KeyboardInterrupt: raise 717 except: pass 718 719 # This fallback shouldn't usually be needed. But it is needed in 720 # a couple special cases (including using epydoc to document 721 # itself). In particular, if a module gets loaded twice, using 722 # two different names for the same file, then this helps. 723 for module in sys.modules.values(): 724 if (hasattr(module, '__dict__') and 725 hasattr(func, 'func_globals') and 726 func.func_globals is module.__dict__): 727 return module.__name__ 728 return None
    729 730 #//////////////////////////////////////////////////////////// 731 # Introspection Dispatch Table 732 #//////////////////////////////////////////////////////////// 733 734 _introspecter_registry = []
    735 -def register_introspecter(applicability_test, introspecter, priority=10):
    736 """ 737 Register an introspecter function. Introspecter functions take 738 two arguments, a python value and a C{ValueDoc} object, and should 739 add information about the given value to the the C{ValueDoc}. 740 Usually, the first line of an inspecter function will specialize 741 it to a sublass of C{ValueDoc}, using L{ValueDoc.specialize_to()}: 742 743 >>> def typical_introspecter(value, value_doc): 744 ... value_doc.specialize_to(SomeSubclassOfValueDoc) 745 ... <add info to value_doc> 746 747 @param priority: The priority of this introspecter, which determines 748 the order in which introspecters are tried -- introspecters with lower 749 numbers are tried first. The standard introspecters have priorities 750 ranging from 20 to 30. The default priority (10) will place new 751 introspecters before standard introspecters. 752 """ 753 _introspecter_registry.append( (priority, applicability_test, 754 introspecter) ) 755 _introspecter_registry.sort()
    756
    757 -def _get_introspecter(value):
    758 for (priority, applicability_test, introspecter) in _introspecter_registry: 759 if applicability_test(value): 760 return introspecter 761 else: 762 return introspect_other
    763 764 # Register the standard introspecter functions.
    765 -def is_classmethod(v): return isinstance(v, classmethod)
    766 -def is_staticmethod(v): return isinstance(v, staticmethod)
    767 -def is_property(v): return isinstance(v, property)
    768 register_introspecter(inspect.ismodule, introspect_module, priority=20) 769 register_introspecter(isclass, introspect_class, priority=24) 770 register_introspecter(inspect.isroutine, introspect_routine, priority=28) 771 register_introspecter(is_property, introspect_property, priority=30) 772 773 # Register getset_descriptor as a property 774 try: 775 import array 776 getset_type = type(array.array.typecode) 777 del array
    778 - def is_getset(v): return isinstance(v, getset_type)
    779 register_introspecter(is_getset, introspect_property, priority=32) 780 except: 781 pass 782 783 # Register member_descriptor as a property 784 try: 785 import datetime 786 member_type = type(datetime.timedelta.days) 787 del datetime
    788 - def is_member(v): return isinstance(v, member_type)
    789 register_introspecter(is_member, introspect_property, priority=34) 790 except: 791 pass 792 793 #//////////////////////////////////////////////////////////// 794 # Import support 795 #//////////////////////////////////////////////////////////// 796
    797 -def get_value_from_filename(filename, context=None):
    798 # Normalize the filename. 799 filename = os.path.normpath(os.path.abspath(filename)) 800 801 # Divide the filename into a base directory and a name. (For 802 # packages, use the package's parent directory as the base, and 803 # the directory name as its name). 804 basedir = os.path.split(filename)[0] 805 name = os.path.splitext(os.path.split(filename)[1])[0] 806 if name == '__init__': 807 basedir, name = os.path.split(basedir) 808 name = DottedName(name) 809 810 # If the context wasn't provided, then check if the file is in a 811 # package directory. If so, then update basedir & name to contain 812 # the topmost package's directory and the fully qualified name for 813 # this file. (This update assume the default value of __path__ 814 # for the parent packages; if the parent packages override their 815 # __path__s, then this can cause us not to find the value.) 816 if context is None: 817 while is_package_dir(basedir): 818 basedir, pkg_name = os.path.split(basedir) 819 name = DottedName(pkg_name, name) 820 821 # If a parent package was specified, then find the directory of 822 # the topmost package, and the fully qualified name for this file. 823 if context is not None: 824 # Combine the name. 825 name = DottedName(context.canonical_name, name) 826 # Find the directory of the base package. 827 while context not in (None, UNKNOWN): 828 pkg_dir = os.path.split(context.filename)[0] 829 basedir = os.path.split(pkg_dir)[0] 830 context = context.package 831 832 # Import the module. (basedir is the directory of the module's 833 # topmost package, or its own directory if it's not in a package; 834 # and name is the fully qualified dotted name for the module.) 835 old_sys_path = sys.path[:] 836 try: 837 sys.path.insert(0, basedir) 838 # This will make sure that we get the module itself, even 839 # if it is shadowed by a variable. (E.g., curses.wrapper): 840 _import(str(name)) 841 if str(name) in sys.modules: 842 return sys.modules[str(name)] 843 else: 844 # Use this as a fallback -- it *shouldn't* ever be needed. 845 return get_value_from_name(name) 846 finally: 847 sys.path = old_sys_path
    848
    849 -def get_value_from_scriptname(filename):
    852
    853 -def get_value_from_name(name, globs=None):
    854 """ 855 Given a name, return the corresponding value. 856 857 @param globs: A namespace to check for the value, if there is no 858 module containing the named value. Defaults to __builtin__. 859 """ 860 name = DottedName(name) 861 862 # Import the topmost module/package. If we fail, then check if 863 # the requested name refers to a builtin. 864 try: 865 module = _import(name[0]) 866 except ImportError, e: 867 if globs is None: globs = __builtin__.__dict__ 868 if name[0] in globs: 869 try: return _lookup(globs[name[0]], name[1:]) 870 except: raise e 871 else: 872 raise 873 874 # Find the requested value in the module/package or its submodules. 875 for i in range(1, len(name)): 876 try: return _lookup(module, name[i:]) 877 except ImportError: pass 878 module = _import('.'.join(name[:i+1])) 879 module = _lookup(module, name[1:i+1]) 880 return module
    881
    882 -def _lookup(module, name):
    883 val = module 884 for i, identifier in enumerate(name): 885 try: val = getattr(val, identifier) 886 except AttributeError: 887 exc_msg = ('no variable named %s in %s' % 888 (identifier, '.'.join(name[:1+i]))) 889 raise ImportError(exc_msg) 890 return val
    891
    892 -def _import(name, filename=None):
    893 """ 894 Run the given callable in a 'sandboxed' environment. 895 Currently, this includes saving and restoring the contents of 896 sys and __builtins__; and suppressing stdin, stdout, and stderr. 897 """ 898 # Note that we just do a shallow copy of sys. In particular, 899 # any changes made to sys.modules will be kept. But we do 900 # explicitly store sys.path. 901 old_sys = sys.__dict__.copy() 902 old_sys_path = sys.path[:] 903 old_builtins = __builtin__.__dict__.copy() 904 905 # Add the current directory to sys.path, in case they're trying to 906 # import a module by name that resides in the current directory. 907 # But add it to the end -- otherwise, the explicit directory added 908 # in get_value_from_filename might get overwritten 909 sys.path.append('') 910 911 # Suppress input and output. (These get restored when we restore 912 # sys to old_sys). 913 sys.stdin = sys.stdout = sys.stderr = _dev_null 914 sys.__stdin__ = sys.__stdout__ = sys.__stderr__ = _dev_null 915 916 # Remove any command-line arguments 917 sys.argv = ['(imported)'] 918 919 try: 920 try: 921 if filename is None: 922 return __import__(name) 923 else: 924 # For importing scripts: 925 return imp.load_source(name, filename) 926 except KeyboardInterrupt: raise 927 except: 928 exc_typ, exc_val, exc_tb = sys.exc_info() 929 if exc_val is None: 930 estr = '%s' % (exc_typ,) 931 else: 932 estr = '%s: %s' % (exc_typ.__name__, exc_val) 933 if exc_tb.tb_next is not None: 934 estr += ' (line %d)' % (exc_tb.tb_next.tb_lineno,) 935 raise ImportError(estr) 936 finally: 937 # Restore the important values that we saved. 938 __builtin__.__dict__.clear() 939 __builtin__.__dict__.update(old_builtins) 940 sys.__dict__.clear() 941 sys.__dict__.update(old_sys) 942 sys.path = old_sys_path
    943
    944 -def introspect_docstring_lineno(api_doc):
    945 """ 946 Try to determine the line number on which the given item's 947 docstring begins. Return the line number, or C{None} if the line 948 number can't be determined. The line number of the first line in 949 the file is 1. 950 """ 951 if api_doc.docstring_lineno is not UNKNOWN: 952 return api_doc.docstring_lineno 953 if isinstance(api_doc, ValueDoc) and api_doc.pyval is not UNKNOWN: 954 try: 955 lines, lineno = inspect.findsource(api_doc.pyval) 956 if not isinstance(api_doc, ModuleDoc): lineno += 1 957 for lineno in range(lineno, len(lines)): 958 if lines[lineno].split('#', 1)[0].strip(): 959 api_doc.docstring_lineno = lineno + 1 960 return lineno + 1 961 except IOError: pass 962 except TypeError: pass 963 except IndexError: 964 log.warning('inspect.findsource(%s) raised IndexError' 965 % api_doc.canonical_name) 966 return None
    967
    968 -class _DevNull:
    969 """ 970 A "file-like" object that discards anything that is written and 971 always reports end-of-file when read. C{_DevNull} is used by 972 L{_import()} to discard output when importing modules; and to 973 ensure that stdin appears closed. 974 """
    975 - def __init__(self):
    976 self.closed = 1 977 self.mode = 'r+' 978 self.softspace = 0 979 self.name='</dev/null>'
    980 - def close(self): pass
    981 - def flush(self): pass
    982 - def read(self, size=0): return ''
    983 - def readline(self, size=0): return ''
    984 - def readlines(self, sizehint=0): return []
    985 - def seek(self, offset, whence=0): pass
    986 - def tell(self): return 0L
    987 - def truncate(self, size=0): pass
    988 - def write(self, str): pass
    989 - def writelines(self, sequence): pass
    990 xreadlines = readlines
    991 _dev_null = _DevNull() 992 993 ###################################################################### 994 ## Zope InterfaceClass 995 ###################################################################### 996 997 try: 998 from zope.interface.interface import InterfaceClass as _ZopeInterfaceClass 999 register_class_type(_ZopeInterfaceClass) 1000 except: 1001 pass 1002 1003 ###################################################################### 1004 ## Zope Extension classes 1005 ###################################################################### 1006 1007 try: 1008 # Register type(ExtensionClass.ExtensionClass) 1009 from ExtensionClass import ExtensionClass as _ExtensionClass 1010 _ZopeType = type(_ExtensionClass)
    1011 - def _is_zope_type(val):
    1012 return isinstance(val, _ZopeType)
    1013 register_introspecter(_is_zope_type, introspect_class) 1014 1015 # Register ExtensionClass.*MethodType 1016 from ExtensionClass import PythonMethodType as _ZopeMethodType 1017 from ExtensionClass import ExtensionMethodType as _ZopeCMethodType
    1018 - def _is_zope_method(val):
    1019 return isinstance(val, (_ZopeMethodType, _ZopeCMethodType))
    1020 register_introspecter(_is_zope_method, introspect_routine) 1021 except: 1022 pass 1023 1024 1025 1026 1027 # [xx] 1028 0 # hm.. otherwise the following gets treated as a docstring! ouch! 1029 """ 1030 ###################################################################### 1031 ## Zope Extension... 1032 ###################################################################### 1033 class ZopeIntrospecter(Introspecter): 1034 VALUEDOC_CLASSES = Introspecter.VALUEDOC_CLASSES.copy() 1035 VALUEDOC_CLASSES.update({ 1036 'module': ZopeModuleDoc, 1037 'class': ZopeClassDoc, 1038 'interface': ZopeInterfaceDoc, 1039 'attribute': ZopeAttributeDoc, 1040 }) 1041 1042 def add_module_child(self, child, child_name, module_doc): 1043 if isinstance(child, zope.interfaces.Interface): 1044 module_doc.add_zope_interface(child_name) 1045 else: 1046 Introspecter.add_module_child(self, child, child_name, module_doc) 1047 1048 def add_class_child(self, child, child_name, class_doc): 1049 if isinstance(child, zope.interfaces.Interface): 1050 class_doc.add_zope_interface(child_name) 1051 else: 1052 Introspecter.add_class_child(self, child, child_name, class_doc) 1053 1054 def introspect_zope_interface(self, interface, interfacename): 1055 pass # etc... 1056 """ 1057

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.apidoc-module.html0000644000175000017500000000643610750103050023170 0ustar pronovicpronovic apidoc

    Module apidoc


    Classes

    APIDoc
    ClassDoc
    ClassMethodDoc
    DocIndex
    DottedName
    GenericValueDoc
    ModuleDoc
    NamespaceDoc
    PropertyDoc
    RoutineDoc
    StaticMethodDoc
    ValueDoc
    VariableDoc

    Functions

    pp_apidoc
    reachable_valdocs

    Variables

    UNKNOWN

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html-pysrc.html0000644000175000017500000402141410750103050023763 0ustar pronovicpronovic epydoc.docwriter.html
    Package epydoc :: Package docwriter :: Module html
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.html

       1  # 
       2  # epydoc -- HTML output generator 
       3  # Edward Loper 
       4  # 
       5  # Created [01/30/01 05:18 PM] 
       6  # $Id: html.py 1674 2008-01-29 06:03:36Z edloper $ 
       7  # 
       8   
       9  """ 
      10  The HTML output generator for epydoc.  The main interface provided by 
      11  this module is the L{HTMLWriter} class. 
      12   
      13  @todo: Add a cache to L{HTMLWriter.url()}? 
      14  """ 
      15  __docformat__ = 'epytext en' 
      16   
      17  import re, os, sys, codecs, sre_constants, pprint, base64 
      18  import urllib 
      19  import __builtin__ 
      20  from epydoc.apidoc import * 
      21  import epydoc.docstringparser 
      22  import time, epydoc, epydoc.markup, epydoc.markup.epytext 
      23  from epydoc.docwriter.html_colorize import PythonSourceColorizer 
      24  from epydoc.docwriter import html_colorize 
      25  from epydoc.docwriter.html_css import STYLESHEETS 
      26  from epydoc.docwriter.html_help import HTML_HELP 
      27  from epydoc.docwriter.dotgraph import * 
      28  from epydoc import log 
      29  from epydoc.util import plaintext_to_html, is_src_filename 
      30  from epydoc.compat import * # Backwards compatibility 
      31   
      32  ###################################################################### 
      33  ## Template Compiler 
      34  ###################################################################### 
      35  # The compile_template() method defined in this section is used to 
      36  # define several of HTMLWriter's methods. 
      37   
    
    38 -def compile_template(docstring, template_string, 39 output_function='out', debug=epydoc.DEBUG):
    40 """ 41 Given a template string containing inline python source code, 42 return a python function that will fill in the template, and 43 output the result. The signature for this function is taken from 44 the first line of C{docstring}. Output is generated by making 45 repeated calls to the output function with the given name (which 46 is typically one of the function's parameters). 47 48 The templating language used by this function passes through all 49 text as-is, with three exceptions: 50 51 - If every line in the template string is indented by at least 52 M{x} spaces, then the first M{x} spaces are stripped from each 53 line. 54 55 - Any line that begins with '>>>' (with no indentation) 56 should contain python code, and will be inserted as-is into 57 the template-filling function. If the line begins a control 58 block (such as 'if' or 'for'), then the control block will 59 be closed by the first '>>>'-marked line whose indentation is 60 less than or equal to the line's own indentation (including 61 lines that only contain comments.) 62 63 - In any other line, any expression between two '$' signs will 64 be evaluated and inserted into the line (using C{str()} to 65 convert the result to a string). 66 67 Here is a simple example: 68 69 >>> TEMPLATE = ''' 70 ... <book> 71 ... <title>$book.title$</title> 72 ... <pages>$book.count_pages()$</pages> 73 ... >>> for chapter in book.chapters: 74 ... <chaptername>$chapter.name$</chaptername> 75 ... >>> #endfor 76 ... </book> 77 >>> write_book = compile_template('write_book(out, book)', TEMPLATE) 78 79 @newfield acknowledgements: Acknowledgements 80 @acknowledgements: The syntax used by C{compile_template} is 81 loosely based on Cheetah. 82 """ 83 # Extract signature from the docstring: 84 signature = docstring.lstrip().split('\n',1)[0].strip() 85 func_name = signature.split('(',1)[0].strip() 86 87 # Regexp to search for inline substitutions: 88 INLINE = re.compile(r'\$([^\$]+)\$') 89 # Regexp to search for python statements in the template: 90 COMMAND = re.compile(r'(^>>>.*)\n?', re.MULTILINE) 91 92 # Strip indentation from the template. 93 template_string = strip_indent(template_string) 94 95 # If we're debugging, then we'll store the generated function, 96 # so we can print it along with any tracebacks that depend on it. 97 if debug: 98 signature = re.sub(r'\)\s*$', ', __debug=__debug)', signature) 99 100 # Funciton declaration line 101 pysrc_lines = ['def %s:' % signature] 102 indents = [-1] 103 104 if debug: 105 pysrc_lines.append(' try:') 106 indents.append(-1) 107 108 commands = COMMAND.split(template_string.strip()+'\n') 109 for i, command in enumerate(commands): 110 if command == '': continue 111 112 # String literal segment: 113 if i%2 == 0: 114 pieces = INLINE.split(command) 115 for j, piece in enumerate(pieces): 116 if j%2 == 0: 117 # String piece 118 pysrc_lines.append(' '*len(indents)+ 119 '%s(%r)' % (output_function, piece)) 120 else: 121 # Variable piece 122 pysrc_lines.append(' '*len(indents)+ 123 '%s(unicode(%s))' % (output_function, piece)) 124 125 # Python command: 126 else: 127 srcline = command[3:].lstrip() 128 # Update indentation 129 indent = len(command)-len(srcline) 130 while indent <= indents[-1]: indents.pop() 131 # Add on the line. 132 srcline = srcline.rstrip() 133 pysrc_lines.append(' '*len(indents)+srcline) 134 if srcline.endswith(':'): 135 indents.append(indent) 136 137 if debug: 138 pysrc_lines.append(' except Exception,e:') 139 pysrc_lines.append(' pysrc, func_name = __debug ') 140 pysrc_lines.append(' lineno = sys.exc_info()[2].tb_lineno') 141 pysrc_lines.append(' print ("Exception in template %s() on "') 142 pysrc_lines.append(' "line %d:" % (func_name, lineno))') 143 pysrc_lines.append(' print pysrc[lineno-1]') 144 pysrc_lines.append(' raise') 145 146 pysrc = '\n'.join(pysrc_lines)+'\n' 147 #log.debug(pysrc) 148 if debug: localdict = {'__debug': (pysrc_lines, func_name)} 149 else: localdict = {} 150 try: exec pysrc in globals(), localdict 151 except SyntaxError: 152 log.error('Error in script:\n' + pysrc + '\n') 153 raise 154 template_func = localdict[func_name] 155 template_func.__doc__ = docstring 156 return template_func
    157
    158 -def strip_indent(s):
    159 """ 160 Given a multiline string C{s}, find the minimum indentation for 161 all non-blank lines, and return a new string formed by stripping 162 that amount of indentation from all lines in C{s}. 163 """ 164 # Strip indentation from the template. 165 minindent = sys.maxint 166 lines = s.split('\n') 167 for line in lines: 168 stripline = line.lstrip() 169 if stripline: 170 minindent = min(minindent, len(line)-len(stripline)) 171 return '\n'.join([l[minindent:] for l in lines])
    172 173 ###################################################################### 174 ## HTML Writer 175 ###################################################################### 176
    177 -class HTMLWriter:
    178 #//////////////////////////////////////////////////////////// 179 # Table of Contents 180 #//////////////////////////////////////////////////////////// 181 # 182 # 1. Interface Methods 183 # 184 # 2. Page Generation -- write complete web page files 185 # 2.1. Module Pages 186 # 2.2. Class Pages 187 # 2.3. Trees Page 188 # 2.4. Indices Page 189 # 2.5. Help Page 190 # 2.6. Frames-based table of contents pages 191 # 2.7. Homepage (index.html) 192 # 2.8. CSS Stylesheet 193 # 2.9. Javascript file 194 # 2.10. Graphs 195 # 2.11. Images 196 # 197 # 3. Page Element Generation -- write pieces of a web page file 198 # 3.1. Page Header 199 # 3.2. Page Footer 200 # 3.3. Navigation Bar 201 # 3.4. Breadcrumbs 202 # 3.5. Summary Tables 203 # 204 # 4. Helper functions 205
    206 - def __init__(self, docindex, **kwargs):
    207 """ 208 Construct a new HTML writer, using the given documentation 209 index. 210 211 @param docindex: The documentation index. 212 213 @type prj_name: C{string} 214 @keyword prj_name: The name of the project. Defaults to 215 none. 216 @type prj_url: C{string} 217 @keyword prj_url: The target for the project hopeage link on 218 the navigation bar. If C{prj_url} is not specified, 219 then no hyperlink is created. 220 @type prj_link: C{string} 221 @keyword prj_link: The label for the project link on the 222 navigation bar. This link can contain arbitrary HTML 223 code (e.g. images). By default, a label is constructed 224 from C{prj_name}. 225 @type top_page: C{string} 226 @keyword top_page: The top page for the documentation. This 227 is the default page shown main frame, when frames are 228 enabled. C{top} can be a URL, the name of a 229 module, the name of a class, or one of the special 230 strings C{"trees.html"}, C{"indices.html"}, or 231 C{"help.html"}. By default, the top-level package or 232 module is used, if there is one; otherwise, C{"trees"} 233 is used. 234 @type css: C{string} 235 @keyword css: The CSS stylesheet file. If C{css} is a file 236 name, then the specified file's conents will be used. 237 Otherwise, if C{css} is the name of a CSS stylesheet in 238 L{epydoc.docwriter.html_css}, then that stylesheet will 239 be used. Otherwise, an error is reported. If no stylesheet 240 is specified, then the default stylesheet is used. 241 @type help_file: C{string} 242 @keyword help_file: The name of the help file. If no help file is 243 specified, then the default help file will be used. 244 @type show_private: C{boolean} 245 @keyword show_private: Whether to create documentation for 246 private objects. By default, private objects are documented. 247 @type show_frames: C{boolean}) 248 @keyword show_frames: Whether to create a frames-based table of 249 contents. By default, it is produced. 250 @type show_imports: C{boolean} 251 @keyword show_imports: Whether or not to display lists of 252 imported functions and classes. By default, they are 253 not shown. 254 @type variable_maxlines: C{int} 255 @keyword variable_maxlines: The maximum number of lines that 256 should be displayed for the value of a variable in the 257 variable details section. By default, 8 lines are 258 displayed. 259 @type variable_linelength: C{int} 260 @keyword variable_linelength: The maximum line length used for 261 displaying the values of variables in the variable 262 details sections. If a line is longer than this length, 263 then it will be wrapped to the next line. The default 264 line length is 70 characters. 265 @type variable_summary_linelength: C{int} 266 @keyword variable_summary_linelength: The maximum line length 267 used for displaying the values of variables in the summary 268 section. If a line is longer than this length, then it 269 will be truncated. The default is 40 characters. 270 @type variable_tooltip_linelength: C{int} 271 @keyword variable_tooltip_linelength: The maximum line length 272 used for tooltips for the values of variables. If a 273 line is longer than this length, then it will be 274 truncated. The default is 600 characters. 275 @type property_function_linelength: C{int} 276 @keyword property_function_linelength: The maximum line length 277 used to dispaly property functions (C{fget}, C{fset}, and 278 C{fdel}) that contain something other than a function 279 object. The default length is 40 characters. 280 @type inheritance: C{string} 281 @keyword inheritance: How inherited objects should be displayed. 282 If C{inheritance='grouped'}, then inherited objects are 283 gathered into groups; if C{inheritance='listed'}, then 284 inherited objects are listed in a short list at the 285 end of their group; if C{inheritance='included'}, then 286 inherited objects are mixed in with non-inherited 287 objects. The default is 'grouped'. 288 @type include_source_code: C{boolean} 289 @keyword include_source_code: If true, then generate colorized 290 source code files for each python module. 291 @type include_log: C{boolean} 292 @keyword include_log: If true, the the footer will include an 293 href to the page 'epydoc-log.html'. 294 @type src_code_tab_width: C{int} 295 @keyword src_code_tab_width: Number of spaces to replace each tab 296 with in source code listings. 297 """ 298 self.docindex = docindex 299 300 # Process keyword arguments. 301 self._show_private = kwargs.get('show_private', 1) 302 """Should private docs be included?""" 303 304 self._prj_name = kwargs.get('prj_name', None) 305 """The project's name (for the project link in the navbar)""" 306 307 self._prj_url = kwargs.get('prj_url', None) 308 """URL for the project link in the navbar""" 309 310 self._prj_link = kwargs.get('prj_link', None) 311 """HTML code for the project link in the navbar""" 312 313 self._top_page = kwargs.get('top_page', None) 314 """The 'main' page""" 315 316 self._css = kwargs.get('css') 317 """CSS stylesheet to use""" 318 319 self._helpfile = kwargs.get('help_file', None) 320 """Filename of file to extract help contents from""" 321 322 self._frames_index = kwargs.get('show_frames', 1) 323 """Should a frames index be created?""" 324 325 self._show_imports = kwargs.get('show_imports', False) 326 """Should imports be listed?""" 327 328 self._propfunc_linelen = kwargs.get('property_function_linelength', 40) 329 """[XXX] Not used!""" 330 331 self._variable_maxlines = kwargs.get('variable_maxlines', 8) 332 """Max lines for variable values""" 333 334 self._variable_linelen = kwargs.get('variable_linelength', 70) 335 """Max line length for variable values""" 336 337 self._variable_summary_linelen = \ 338 kwargs.get('variable_summary_linelength', 65) 339 """Max length for variable value summaries""" 340 341 self._variable_tooltip_linelen = \ 342 kwargs.get('variable_tooltip_linelength', 600) 343 """Max length for variable tooltips""" 344 345 self._inheritance = kwargs.get('inheritance', 'listed') 346 """How should inheritance be displayed? 'listed', 'included', 347 or 'grouped'""" 348 349 self._incl_sourcecode = kwargs.get('include_source_code', True) 350 """Should pages be generated for source code of modules?""" 351 352 self._mark_docstrings = kwargs.get('mark_docstrings', False) 353 """Wrap <span class='docstring'>...</span> around docstrings?""" 354 355 self._graph_types = kwargs.get('graphs', ()) or () 356 """Graphs that we should include in our output.""" 357 358 self._include_log = kwargs.get('include_log', False) 359 """Are we generating an HTML log page?""" 360 361 self._src_code_tab_width = kwargs.get('src_code_tab_width', 8) 362 """Number of spaces to replace each tab with in source code 363 listings.""" 364 365 self._callgraph_cache = {} 366 """Map the callgraph L{uid<DotGraph.uid>} to their HTML 367 representation.""" 368 369 self._redundant_details = kwargs.get('redundant_details', False) 370 """If true, then include objects in the details list even if all 371 info about them is already provided by the summary table.""" 372 373 # For use with select_variables(): 374 if self._show_private: 375 self._public_filter = None 376 else: 377 self._public_filter = True 378 379 # Make sure inheritance has a sane value. 380 if self._inheritance not in ('listed', 'included', 'grouped'): 381 raise ValueError, 'Bad value for inheritance' 382 383 # Create the project homepage link, if it was not specified. 384 if (self._prj_name or self._prj_url) and not self._prj_link: 385 self._prj_link = plaintext_to_html(self._prj_name or 386 'Project Homepage') 387 388 # Add a hyperlink to _prj_url, if _prj_link doesn't already 389 # contain any hyperlinks. 390 if (self._prj_link and self._prj_url and 391 not re.search(r'<a[^>]*\shref', self._prj_link)): 392 self._prj_link = ('<a class="navbar" target="_top" href="'+ 393 self._prj_url+'">'+self._prj_link+'</a>') 394 395 # Precompute lists & sets of APIDoc objects that we're 396 # interested in. 397 self.valdocs = valdocs = sorted(docindex.reachable_valdocs( 398 imports=False, packages=False, bases=False, submodules=False, 399 subclasses=False, private=self._show_private)) 400 self.module_list = [d for d in valdocs if isinstance(d, ModuleDoc)] 401 """The list of L{ModuleDoc}s for the documented modules.""" 402 self.module_set = set(self.module_list) 403 """The set of L{ModuleDoc}s for the documented modules.""" 404 self.class_list = [d for d in valdocs if isinstance(d, ClassDoc)] 405 """The list of L{ClassDoc}s for the documented classes.""" 406 self.class_set = set(self.class_list) 407 """The set of L{ClassDoc}s for the documented classes.""" 408 self.routine_list = [d for d in valdocs if isinstance(d, RoutineDoc)] 409 """The list of L{RoutineDoc}s for the documented routines.""" 410 self.indexed_docs = [] 411 """The list of L{APIDoc}s for variables and values that should 412 be included in the index.""" 413 414 # URL for 'trees' page 415 if self.module_list: self._trees_url = 'module-tree.html' 416 else: self._trees_url = 'class-tree.html' 417 418 # Construct the value for self.indexed_docs. 419 self.indexed_docs += [d for d in valdocs 420 if not isinstance(d, GenericValueDoc)] 421 for doc in valdocs: 422 if isinstance(doc, NamespaceDoc): 423 # add any vars with generic values; but don't include 424 # inherited vars. 425 self.indexed_docs += [d for d in doc.variables.values() if 426 isinstance(d.value, GenericValueDoc) 427 and d.container == doc] 428 self.indexed_docs.sort() 429 430 # Figure out the url for the top page. 431 self._top_page_url = self._find_top_page(self._top_page) 432 433 # Decide whether or not to split the identifier index. 434 self._split_ident_index = (len(self.indexed_docs) >= 435 self.SPLIT_IDENT_INDEX_SIZE) 436 437 # Figure out how many output files there will be (for progress 438 # reporting). 439 self.modules_with_sourcecode = set() 440 for doc in self.module_list: 441 if isinstance(doc, ModuleDoc) and is_src_filename(doc.filename): 442 self.modules_with_sourcecode.add(doc) 443 self._num_files = (len(self.class_list) + len(self.module_list) + 444 10 + len(self.METADATA_INDICES)) 445 if self._frames_index: 446 self._num_files += len(self.module_list) + 3 447 448 if self._incl_sourcecode: 449 self._num_files += len(self.modules_with_sourcecode) 450 if self._split_ident_index: 451 self._num_files += len(self.LETTERS)
    452
    453 - def _find_top_page(self, pagename):
    454 """ 455 Find the top page for the API documentation. This page is 456 used as the default page shown in the main frame, when frames 457 are used. When frames are not used, this page is copied to 458 C{index.html}. 459 460 @param pagename: The name of the page, as specified by the 461 keyword argument C{top} to the constructor. 462 @type pagename: C{string} 463 @return: The URL of the top page. 464 @rtype: C{string} 465 """ 466 # If a page name was specified, then we need to figure out 467 # what it points to. 468 if pagename: 469 # If it's a URL, then use it directly. 470 if pagename.lower().startswith('http:'): 471 return pagename 472 473 # If it's an object, then use that object's page. 474 try: 475 doc = self.docindex.get_valdoc(pagename) 476 return self.url(doc) 477 except: 478 pass 479 480 # Otherwise, give up. 481 log.warning('Could not find top page %r; using %s ' 482 'instead' % (pagename, self._trees_url)) 483 return self._trees_url 484 485 # If no page name was specified, then try to choose one 486 # automatically. 487 else: 488 root = [val_doc for val_doc in self.docindex.root 489 if isinstance(val_doc, (ClassDoc, ModuleDoc))] 490 if len(root) == 0: 491 # No docs?? Try the trees page. 492 return self._trees_url 493 elif len(root) == 1: 494 # One item in the root; use that. 495 return self.url(root[0]) 496 else: 497 # Multiple root items; if they're all in one package, 498 # then use that. Otherwise, use self._trees_url 499 root = sorted(root, key=lambda v:len(v.canonical_name)) 500 top = root[0] 501 for doc in root[1:]: 502 if not top.canonical_name.dominates(doc.canonical_name): 503 return self._trees_url 504 else: 505 return self.url(top)
    506 507 #//////////////////////////////////////////////////////////// 508 #{ 1. Interface Methods 509 #//////////////////////////////////////////////////////////// 510
    511 - def write(self, directory=None):
    512 """ 513 Write the documentation to the given directory. 514 515 @type directory: C{string} 516 @param directory: The directory to which output should be 517 written. If no directory is specified, output will be 518 written to the current directory. If the directory does 519 not exist, it will be created. 520 @rtype: C{None} 521 @raise OSError: If C{directory} cannot be created. 522 @raise OSError: If any file cannot be created or written to. 523 """ 524 # For progress reporting: 525 self._files_written = 0. 526 527 # Set the default values for ValueDoc formatted representations. 528 orig_valdoc_defaults = (ValueDoc.SUMMARY_REPR_LINELEN, 529 ValueDoc.REPR_LINELEN, 530 ValueDoc.REPR_MAXLINES) 531 ValueDoc.SUMMARY_REPR_LINELEN = self._variable_summary_linelen 532 ValueDoc.REPR_LINELEN = self._variable_linelen 533 ValueDoc.REPR_MAXLINES = self._variable_maxlines 534 535 # Use an image for the crarr symbol. 536 from epydoc.markup.epytext import ParsedEpytextDocstring 537 orig_crarr_html = ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] 538 ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = ( 539 r'<span class="variable-linewrap">' 540 r'<img src="crarr.png" alt="\" /></span>') 541 542 # Keep track of failed xrefs, and report them at the end. 543 self._failed_xrefs = {} 544 545 # Create destination directories, if necessary 546 if not directory: directory = os.curdir 547 self._mkdir(directory) 548 self._directory = directory 549 550 # Write the CSS file. 551 self._files_written += 1 552 log.progress(self._files_written/self._num_files, 'epydoc.css') 553 self.write_css(directory, self._css) 554 555 # Write the Javascript file. 556 self._files_written += 1 557 log.progress(self._files_written/self._num_files, 'epydoc.js') 558 self.write_javascript(directory) 559 560 # Write images 561 self.write_images(directory) 562 563 # Build the indices. 564 indices = {'ident': self.build_identifier_index(), 565 'term': self.build_term_index()} 566 for (name, label, label2) in self.METADATA_INDICES: 567 indices[name] = self.build_metadata_index(name) 568 569 # Write the identifier index. If requested, split it into 570 # separate pages for each letter. 571 ident_by_letter = self._group_by_letter(indices['ident']) 572 if not self._split_ident_index: 573 self._write(self.write_link_index, directory, 574 'identifier-index.html', indices, 575 'Identifier Index', 'identifier-index.html', 576 ident_by_letter) 577 else: 578 # Write a page for each section. 579 for letter in self.LETTERS: 580 filename = 'identifier-index-%s.html' % letter 581 self._write(self.write_link_index, directory, filename, 582 indices, 'Identifier Index', filename, 583 ident_by_letter, [letter], 584 'identifier-index-%s.html') 585 # Use the first non-empty section as the main index page. 586 for letter in self.LETTERS: 587 if letter in ident_by_letter: 588 filename = 'identifier-index.html' 589 self._write(self.write_link_index, directory, filename, 590 indices, 'Identifier Index', filename, 591 ident_by_letter, [letter], 592 'identifier-index-%s.html') 593 break 594 595 # Write the term index. 596 if indices['term']: 597 term_by_letter = self._group_by_letter(indices['term']) 598 self._write(self.write_link_index, directory, 'term-index.html', 599 indices, 'Term Definition Index', 600 'term-index.html', term_by_letter) 601 else: 602 self._files_written += 1 # (skipped) 603 604 # Write the metadata indices. 605 for (name, label, label2) in self.METADATA_INDICES: 606 if indices[name]: 607 self._write(self.write_metadata_index, directory, 608 '%s-index.html' % name, indices, name, 609 label, label2) 610 else: 611 self._files_written += 1 # (skipped) 612 613 # Write the trees file (package & class hierarchies) 614 if self.module_list: 615 self._write(self.write_module_tree, directory, 'module-tree.html') 616 else: 617 self._files_written += 1 # (skipped) 618 if self.class_list: 619 self._write(self.write_class_tree, directory, 'class-tree.html') 620 else: 621 self._files_written += 1 # (skipped) 622 623 # Write the help file. 624 self._write(self.write_help, directory,'help.html') 625 626 # Write the frames-based table of contents. 627 if self._frames_index: 628 self._write(self.write_frames_index, directory, 'frames.html') 629 self._write(self.write_toc, directory, 'toc.html') 630 self._write(self.write_project_toc, directory, 'toc-everything.html') 631 for doc in self.module_list: 632 filename = 'toc-%s' % urllib.unquote(self.url(doc)) 633 self._write(self.write_module_toc, directory, filename, doc) 634 635 # Write the object documentation. 636 for doc in self.module_list: 637 filename = urllib.unquote(self.url(doc)) 638 self._write(self.write_module, directory, filename, doc) 639 for doc in self.class_list: 640 filename = urllib.unquote(self.url(doc)) 641 self._write(self.write_class, directory, filename, doc) 642 643 # Write source code files. 644 if self._incl_sourcecode: 645 # Build a map from short names to APIDocs, used when 646 # linking names in the source code. 647 name_to_docs = {} 648 for api_doc in self.indexed_docs: 649 if (api_doc.canonical_name is not None and 650 self.url(api_doc) is not None): 651 name = api_doc.canonical_name[-1] 652 name_to_docs.setdefault(name, []).append(api_doc) 653 # Sort each entry of the name_to_docs list. 654 for doc_list in name_to_docs.values(): 655 doc_list.sort() 656 # Write the source code for each module. 657 for doc in self.modules_with_sourcecode: 658 filename = urllib.unquote(self.pysrc_url(doc)) 659 self._write(self.write_sourcecode, directory, filename, doc, 660 name_to_docs) 661 662 # Write the auto-redirect page. 663 self._write(self.write_redirect_page, directory, 'redirect.html') 664 665 # Write the mapping object name -> URL 666 self._write(self.write_api_list, directory, 'api-objects.txt') 667 668 # Write the index.html files. 669 # (this must be done last, since it might copy another file) 670 self._files_written += 1 671 log.progress(self._files_written/self._num_files, 'index.html') 672 self.write_homepage(directory) 673 674 # Don't report references to builtins as missing 675 for k in self._failed_xrefs.keys(): # have a copy of keys 676 if hasattr(__builtin__, k): 677 del self._failed_xrefs[k] 678 679 # Report any failed crossreferences 680 if self._failed_xrefs: 681 estr = 'Failed identifier crossreference targets:\n' 682 failed_identifiers = self._failed_xrefs.keys() 683 failed_identifiers.sort() 684 for identifier in failed_identifiers: 685 names = self._failed_xrefs[identifier].keys() 686 names.sort() 687 estr += '- %s' % identifier 688 estr += '\n' 689 for name in names: 690 estr += ' (from %s)\n' % name 691 log.docstring_warning(estr) 692 693 # [xx] testing: 694 if self._num_files != int(self._files_written): 695 log.debug("Expected to write %d files, but actually " 696 "wrote %d files" % 697 (self._num_files, int(self._files_written))) 698 699 # Restore defaults that we changed. 700 (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, 701 ValueDoc.REPR_MAXLINES) = orig_valdoc_defaults 702 ParsedEpytextDocstring.SYMBOL_TO_HTML['crarr'] = orig_crarr_html
    703
    704 - def _write(self, write_func, directory, filename, *args):
    705 # Display our progress. 706 self._files_written += 1 707 log.progress(self._files_written/self._num_files, filename) 708 709 path = os.path.join(directory, filename) 710 f = codecs.open(path, 'w', 'ascii', errors='xmlcharrefreplace') 711 write_func(f.write, *args) 712 f.close()
    713
    714 - def _mkdir(self, directory):
    715 """ 716 If the given directory does not exist, then attempt to create it. 717 @rtype: C{None} 718 """ 719 if not os.path.isdir(directory): 720 if os.path.exists(directory): 721 raise OSError('%r is not a directory' % directory) 722 os.mkdir(directory)
    723 724 #//////////////////////////////////////////////////////////// 725 #{ 2.1. Module Pages 726 #//////////////////////////////////////////////////////////// 727
    728 - def write_module(self, out, doc):
    729 """ 730 Write an HTML page containing the API documentation for the 731 given module to C{out}. 732 733 @param doc: A L{ModuleDoc} containing the API documentation 734 for the module that should be described. 735 """ 736 longname = doc.canonical_name 737 shortname = doc.canonical_name[-1] 738 739 # Write the page header (incl. navigation bar & breadcrumbs) 740 self.write_header(out, str(longname)) 741 self.write_navbar(out, doc) 742 self.write_breadcrumbs(out, doc, self.url(doc)) 743 744 # Write the name of the module we're describing. 745 if doc.is_package is True: typ = 'Package' 746 else: typ = 'Module' 747 if longname[0].startswith('script-'): 748 shortname = str(longname)[7:] 749 typ = 'Script' 750 out('<!-- ==================== %s ' % typ.upper() + 751 'DESCRIPTION ==================== -->\n') 752 out('<h1 class="epydoc">%s %s</h1>' % (typ, shortname)) 753 out('<p class="nomargin-top">%s</p>\n' % self.pysrc_link(doc)) 754 755 # If the module has a description, then list it. 756 if doc.descr not in (None, UNKNOWN): 757 out(self.descr(doc, 2)+'\n\n') 758 759 # Write any standarad metadata (todo, author, etc.) 760 if doc.metadata is not UNKNOWN and doc.metadata: 761 out('<hr />\n') 762 self.write_standard_fields(out, doc) 763 764 # If it's a package, then list the modules it contains. 765 if doc.is_package is True: 766 self.write_module_list(out, doc) 767 768 # Write summary tables describing the variables that the 769 # module defines. 770 self.write_summary_table(out, "Classes", doc, "class") 771 self.write_summary_table(out, "Functions", doc, "function") 772 self.write_summary_table(out, "Variables", doc, "other") 773 774 # Write a list of all imported objects. 775 if self._show_imports: 776 self.write_imports(out, doc) 777 778 # Write detailed descriptions of functions & variables defined 779 # in this module. 780 self.write_details_list(out, "Function Details", doc, "function") 781 self.write_details_list(out, "Variables Details", doc, "other") 782 783 # Write the page footer (including navigation bar) 784 self.write_navbar(out, doc) 785 self.write_footer(out)
    786 787 #//////////////////////////////////////////////////////////// 788 #{ 2.??. Source Code Pages 789 #//////////////////////////////////////////////////////////// 790
    791 - def write_sourcecode(self, out, doc, name_to_docs):
    792 #t0 = time.time() 793 794 filename = doc.filename 795 name = str(doc.canonical_name) 796 797 # Header 798 self.write_header(out, name) 799 self.write_navbar(out, doc) 800 self.write_breadcrumbs(out, doc, self.pysrc_url(doc)) 801 802 # Source code listing 803 out('<h1 class="epydoc">Source Code for %s</h1>\n' % 804 self.href(doc, label='%s %s' % (self.doc_kind(doc), name))) 805 out('<pre class="py-src">\n') 806 out(PythonSourceColorizer(filename, name, self.docindex, 807 self.url, name_to_docs, 808 self._src_code_tab_width).colorize()) 809 out('</pre>\n<br />\n') 810 811 # Footer 812 self.write_navbar(out, doc) 813 self.write_footer(out)
    814 815 #log.debug('[%6.2f sec] Wrote pysrc for %s' % 816 # (time.time()-t0, name)) 817 818 #//////////////////////////////////////////////////////////// 819 #{ 2.2. Class Pages 820 #//////////////////////////////////////////////////////////// 821
    822 - def write_class(self, out, doc):
    823 """ 824 Write an HTML page containing the API documentation for the 825 given class to C{out}. 826 827 @param doc: A L{ClassDoc} containing the API documentation 828 for the class that should be described. 829 """ 830 longname = doc.canonical_name 831 shortname = doc.canonical_name[-1] 832 833 # Write the page header (incl. navigation bar & breadcrumbs) 834 self.write_header(out, str(longname)) 835 self.write_navbar(out, doc) 836 self.write_breadcrumbs(out, doc, self.url(doc)) 837 838 # Write the name of the class we're describing. 839 if doc.is_type(): typ = 'Type' 840 elif doc.is_exception(): typ = 'Exception' 841 else: typ = 'Class' 842 out('<!-- ==================== %s ' % typ.upper() + 843 'DESCRIPTION ==================== -->\n') 844 out('<h1 class="epydoc">%s %s</h1>' % (typ, shortname)) 845 out('<p class="nomargin-top">%s</p>\n' % self.pysrc_link(doc)) 846 847 if ((doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0) or 848 (doc.subclasses not in (UNKNOWN,None) and len(doc.subclasses)>0)): 849 # Display bases graphically, if requested. 850 if 'umlclasstree' in self._graph_types: 851 self.write_class_tree_graph(out, doc, uml_class_tree_graph) 852 elif 'classtree' in self._graph_types: 853 self.write_class_tree_graph(out, doc, class_tree_graph) 854 855 # Otherwise, use ascii-art. 856 else: 857 # Write the base class tree. 858 if doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0: 859 out('<pre class="base-tree">\n%s</pre>\n\n' % 860 self.base_tree(doc)) 861 862 # Write the known subclasses 863 if (doc.subclasses not in (UNKNOWN, None) and 864 len(doc.subclasses) > 0): 865 out('<dl><dt>Known Subclasses:</dt>\n<dd>\n ') 866 out(' <ul class="subclass-list">\n') 867 for i, subclass in enumerate(doc.subclasses): 868 href = self.href(subclass, context=doc) 869 if self._val_is_public(subclass): css = '' 870 else: css = ' class="private"' 871 if i > 0: href = ', '+href 872 out('<li%s>%s</li>' % (css, href)) 873 out(' </ul>\n') 874 out('</dd></dl>\n\n') 875 876 out('<hr />\n') 877 878 # If the class has a description, then list it. 879 if doc.descr not in (None, UNKNOWN): 880 out(self.descr(doc, 2)+'\n\n') 881 882 # Write any standarad metadata (todo, author, etc.) 883 if doc.metadata is not UNKNOWN and doc.metadata: 884 out('<hr />\n') 885 self.write_standard_fields(out, doc) 886 887 # Write summary tables describing the variables that the 888 # class defines. 889 self.write_summary_table(out, "Nested Classes", doc, "class") 890 self.write_summary_table(out, "Instance Methods", doc, 891 "instancemethod") 892 self.write_summary_table(out, "Class Methods", doc, "classmethod") 893 self.write_summary_table(out, "Static Methods", doc, "staticmethod") 894 self.write_summary_table(out, "Class Variables", doc, 895 "classvariable") 896 self.write_summary_table(out, "Instance Variables", doc, 897 "instancevariable") 898 self.write_summary_table(out, "Properties", doc, "property") 899 900 # Write a list of all imported objects. 901 if self._show_imports: 902 self.write_imports(out, doc) 903 904 # Write detailed descriptions of functions & variables defined 905 # in this class. 906 # [xx] why group methods into one section but split vars into two? 907 # seems like we should either group in both cases or split in both 908 # cases. 909 self.write_details_list(out, "Method Details", doc, "method") 910 self.write_details_list(out, "Class Variable Details", doc, 911 "classvariable") 912 self.write_details_list(out, "Instance Variable Details", doc, 913 "instancevariable") 914 self.write_details_list(out, "Property Details", doc, "property") 915 916 # Write the page footer (including navigation bar) 917 self.write_navbar(out, doc) 918 self.write_footer(out)
    919
    920 - def write_class_tree_graph(self, out, doc, graphmaker):
    921 """ 922 Write HTML code for a class tree graph of C{doc} (a classdoc), 923 using C{graphmaker} to draw the actual graph. C{graphmaker} 924 should be L{class_tree_graph()}, or L{uml_class_tree_graph()}, 925 or any other function with a compatible signature. 926 927 If the given class has any private sublcasses (including 928 recursive subclasses), then two graph images will be generated 929 -- one to display when private values are shown, and the other 930 to display when private values are hidden. 931 """ 932 linker = _HTMLDocstringLinker(self, doc) 933 private_subcls = self._private_subclasses(doc) 934 if private_subcls: 935 out('<center>\n' 936 ' <div class="private">%s</div>\n' 937 ' <div class="public" style="display:none">%s</div>\n' 938 '</center>\n' % 939 (self.render_graph(graphmaker(doc, linker, doc)), 940 self.render_graph(graphmaker(doc, linker, doc, 941 exclude=private_subcls)))) 942 else: 943 out('<center>\n%s\n</center>\n' % 944 self.render_graph(graphmaker(doc, linker, doc)))
    945 946 #//////////////////////////////////////////////////////////// 947 #{ 2.3. Trees pages 948 #//////////////////////////////////////////////////////////// 949
    950 - def write_module_tree(self, out):
    951 # Header material 952 self.write_treepage_header(out, 'Module Hierarchy', 'module-tree.html') 953 out('<h1 class="epydoc">Module Hierarchy</h1>\n') 954 955 # Write entries for all top-level modules/packages. 956 out('<ul class="nomargin-top">\n') 957 for doc in self.module_list: 958 if (doc.package in (None, UNKNOWN) or 959 doc.package not in self.module_set): 960 self.write_module_tree_item(out, doc) 961 out('</ul>\n') 962 963 # Footer material 964 self.write_navbar(out, 'trees') 965 self.write_footer(out)
    966
    967 - def write_class_tree(self, out):
    968 """ 969 Write HTML code for a nested list showing the base/subclass 970 relationships between all documented classes. Each element of 971 the top-level list is a class with no (documented) bases; and 972 under each class is listed all of its subclasses. Note that 973 in the case of multiple inheritance, a class may appear 974 multiple times. 975 976 @todo: For multiple inheritance, don't repeat subclasses the 977 second time a class is mentioned; instead, link to the 978 first mention. 979 """ 980 # [XX] backref for multiple inheritance? 981 # Header material 982 self.write_treepage_header(out, 'Class Hierarchy', 'class-tree.html') 983 out('<h1 class="epydoc">Class Hierarchy</h1>\n') 984 985 # Build a set containing all classes that we should list. 986 # This includes everything in class_list, plus any of those 987 # class' bases, but not undocumented subclasses. 988 class_set = self.class_set.copy() 989 for doc in self.class_list: 990 if doc.bases != UNKNOWN: 991 for base in doc.bases: 992 if base not in class_set: 993 if isinstance(base, ClassDoc): 994 class_set.update(base.mro()) 995 else: 996 # [XX] need to deal with this -- how? 997 pass 998 #class_set.add(base) 999 1000 out('<ul class="nomargin-top">\n') 1001 for doc in sorted(class_set, key=lambda c:c.canonical_name[-1]): 1002 if doc.bases != UNKNOWN and len(doc.bases)==0: 1003 self.write_class_tree_item(out, doc, class_set) 1004 out('</ul>\n') 1005 1006 # Footer material 1007 self.write_navbar(out, 'trees') 1008 self.write_footer(out)
    1009
    1010 - def write_treepage_header(self, out, title, url):
    1011 # Header material. 1012 self.write_header(out, title) 1013 self.write_navbar(out, 'trees') 1014 self.write_breadcrumbs(out, 'trees', url) 1015 if self.class_list and self.module_list: 1016 out('<center><b>\n') 1017 out(' [ <a href="module-tree.html">Module Hierarchy</a>\n') 1018 out(' | <a href="class-tree.html">Class Hierarchy</a> ]\n') 1019 out('</b></center><br />\n')
    1020 1021 1022 #//////////////////////////////////////////////////////////// 1023 #{ 2.4. Index pages 1024 #//////////////////////////////////////////////////////////// 1025 1026 SPLIT_IDENT_INDEX_SIZE = 3000 1027 """If the identifier index has more than this number of entries, 1028 then it will be split into separate pages, one for each 1029 alphabetical section.""" 1030 1031 LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' 1032 """The alphabetical sections that are used for link index pages.""" 1033 1069 1070
    1071 - def write_metadata_index(self, out, indices, field, title, typ):
    1072 """ 1073 Write an HTML page containing a metadata index. 1074 """ 1075 index = indices[field] 1076 1077 # Header material. 1078 self.write_indexpage_header(out, indices, title, 1079 '%s-index.html' % field) 1080 1081 # Page title. 1082 out('<h1 class="epydoc"><a name="%s">%s</a></h1>\n<br />\n' % 1083 (field, title)) 1084 1085 # Index (one section per arg) 1086 for arg in sorted(index): 1087 # Write a section title. 1088 if arg is not None: 1089 if len([1 for (doc, descrs) in index[arg] if 1090 not self._doc_or_ancestor_is_private(doc)]) == 0: 1091 out('<div class="private">') 1092 else: 1093 out('<div>') 1094 self.write_table_header(out, 'metadata-index', arg) 1095 out('</table>') 1096 # List every descr for this arg. 1097 for (doc, descrs) in index[arg]: 1098 if self._doc_or_ancestor_is_private(doc): 1099 out('<div class="private">\n') 1100 else: 1101 out('<div>\n') 1102 out('<table width="100%" class="metadata-index" ' 1103 'bgcolor="#e0e0e0"><tr><td class="metadata-index">') 1104 out('<b>%s in %s</b>' % 1105 (typ, self.href(doc, label=doc.canonical_name))) 1106 out(' <ul class="nomargin">\n') 1107 for descr in descrs: 1108 out(' <li>%s</li>\n' % 1109 self.docstring_to_html(descr,doc,4)) 1110 out(' </ul>\n') 1111 out('</table></div>\n') 1112 1113 # Footer material. 1114 out('<br />') 1115 self.write_navbar(out, 'indices') 1116 self.write_footer(out)
    1117
    1118 - def write_indexpage_header(self, out, indices, title, url):
    1119 """ 1120 A helper for the index page generation functions, which 1121 generates a header that can be used to navigate between the 1122 different indices. 1123 """ 1124 self.write_header(out, title) 1125 self.write_navbar(out, 'indices') 1126 self.write_breadcrumbs(out, 'indices', url) 1127 1128 if (indices['term'] or 1129 [1 for (name,l,l2) in self.METADATA_INDICES if indices[name]]): 1130 out('<center><b>[\n') 1131 out(' <a href="identifier-index.html">Identifiers</a>\n') 1132 if indices['term']: 1133 out('| <a href="term-index.html">Term Definitions</a>\n') 1134 for (name, label, label2) in self.METADATA_INDICES: 1135 if indices[name]: 1136 out('| <a href="%s-index.html">%s</a>\n' % 1137 (name, label2)) 1138 out(']</b></center><br />\n')
    1139
    1140 - def write_index_section(self, out, items, add_blankline=False):
    1141 out('<table class="link-index" width="100%" border="1">\n') 1142 num_rows = (len(items)+2)/3 1143 for row in range(num_rows): 1144 out('<tr>\n') 1145 for col in range(3): 1146 out('<td width="33%" class="link-index">') 1147 i = col*num_rows+row 1148 if i < len(items): 1149 name, url, container = items[col*num_rows+row] 1150 out('<a href="%s">%s</a>' % (url, name)) 1151 if container is not None: 1152 out('<br />\n') 1153 if isinstance(container, ModuleDoc): 1154 label = container.canonical_name 1155 else: 1156 label = container.canonical_name[-1] 1157 out('<span class="index-where">(in&nbsp;%s)' 1158 '</span>' % self.href(container, label)) 1159 else: 1160 out('&nbsp;') 1161 out('</td>\n') 1162 out('</tr>\n') 1163 if add_blankline and num_rows == 1: 1164 blank_cell = '<td class="link-index">&nbsp;</td>' 1165 out('<tr>'+3*blank_cell+'</tr>\n') 1166 out('</table>\n')
    1167 1168 #//////////////////////////////////////////////////////////// 1169 #{ 2.5. Help Page 1170 #//////////////////////////////////////////////////////////// 1171
    1172 - def write_help(self, out):
    1173 """ 1174 Write an HTML help file to the given stream. If 1175 C{self._helpfile} contains a help file, then use it; 1176 otherwise, use the default helpfile from 1177 L{epydoc.docwriter.html_help}. 1178 """ 1179 # todo: optionally parse .rst etc help files? 1180 1181 # Get the contents of the help file. 1182 if self._helpfile: 1183 if os.path.exists(self._helpfile): 1184 try: help = open(self._helpfile).read() 1185 except: raise IOError("Can't open help file: %r" % 1186 self._helpfile) 1187 else: 1188 raise IOError("Can't find help file: %r" % self._helpfile) 1189 else: 1190 if self._prj_name: thisprj = self._prj_name 1191 else: thisprj = 'this project' 1192 help = HTML_HELP % {'this_project':thisprj} 1193 1194 # Insert the help contents into a webpage. 1195 self.write_header(out, 'Help') 1196 self.write_navbar(out, 'help') 1197 self.write_breadcrumbs(out, 'help', 'help.html') 1198 out(help) 1199 self.write_navbar(out, 'help') 1200 self.write_footer(out)
    1201 1202 #//////////////////////////////////////////////////////////// 1203 #{ 2.6. Frames-based Table of Contents 1204 #//////////////////////////////////////////////////////////// 1205 1206 write_frames_index = compile_template( 1207 """ 1208 write_frames_index(self, out) 1209 1210 Write the frames index file for the frames-based table of 1211 contents to the given streams. 1212 """, 1213 # /------------------------- Template -------------------------\ 1214 ''' 1215 <?xml version="1.0" encoding="iso-8859-1"?> 1216 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" 1217 "DTD/xhtml1-frameset.dtd"> 1218 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 1219 <head> 1220 <title> $self._prj_name or "API Documentation"$ </title> 1221 </head> 1222 <frameset cols="20%,80%"> 1223 <frameset rows="30%,70%"> 1224 <frame src="toc.html" name="moduleListFrame" 1225 id="moduleListFrame" /> 1226 <frame src="toc-everything.html" name="moduleFrame" 1227 id="moduleFrame" /> 1228 </frameset> 1229 <frame src="$self._top_page_url$" name="mainFrame" id="mainFrame" /> 1230 </frameset> 1231 </html> 1232 ''') 1233 # \------------------------------------------------------------/ 1234 1235 write_toc = compile_template( 1236 """ 1237 write_toc(self, out) 1238 """, 1239 # /------------------------- Template -------------------------\ 1240 ''' 1241 >>> self.write_header(out, "Table of Contents") 1242 <h1 class="toc">Table&nbsp;of&nbsp;Contents</h1> 1243 <hr /> 1244 <a target="moduleFrame" href="toc-everything.html">Everything</a> 1245 <br /> 1246 >>> self.write_toc_section(out, "Modules", self.module_list) 1247 <hr /> 1248 >>> if self._show_private: 1249 $self.PRIVATE_LINK$ 1250 >>> #endif 1251 >>> self.write_footer(out, short=True) 1252 ''') 1253 # \------------------------------------------------------------/ 1254
    1255 - def write_toc_section(self, out, name, docs, fullname=True):
    1256 if not docs: return 1257 1258 # Assign names to each item, and sort by name. 1259 if fullname: 1260 docs = [(str(d.canonical_name), d) for d in docs] 1261 else: 1262 docs = [(str(d.canonical_name[-1]), d) for d in docs] 1263 docs.sort() 1264 1265 out(' <h2 class="toc">%s</h2>\n' % name) 1266 for label, doc in docs: 1267 doc_url = self.url(doc) 1268 toc_url = 'toc-%s' % doc_url 1269 is_private = self._doc_or_ancestor_is_private(doc) 1270 if is_private: 1271 if not self._show_private: continue 1272 out(' <div class="private">\n') 1273 1274 if isinstance(doc, ModuleDoc): 1275 out(' <a target="moduleFrame" href="%s"\n' 1276 ' onclick="setFrame(\'%s\',\'%s\');"' 1277 ' >%s</a><br />' % (toc_url, toc_url, doc_url, label)) 1278 else: 1279 out(' <a target="mainFrame" href="%s"\n' 1280 ' >%s</a><br />' % (doc_url, label)) 1281 if is_private: 1282 out(' </div>\n')
    1283
    1284 - def write_project_toc(self, out):
    1285 self.write_header(out, "Everything") 1286 out('<h1 class="toc">Everything</h1>\n') 1287 out('<hr />\n') 1288 1289 # List the classes. 1290 self.write_toc_section(out, "All Classes", self.class_list) 1291 1292 # List the functions. 1293 funcs = [d for d in self.routine_list 1294 if not isinstance(self.docindex.container(d), 1295 (ClassDoc, types.NoneType))] 1296 self.write_toc_section(out, "All Functions", funcs) 1297 1298 # List the variables. 1299 vars = [] 1300 for doc in self.module_list: 1301 vars += doc.select_variables(value_type='other', 1302 imported=False, 1303 public=self._public_filter) 1304 self.write_toc_section(out, "All Variables", vars) 1305 1306 # Footer material. 1307 out('<hr />\n') 1308 if self._show_private: 1309 out(self.PRIVATE_LINK+'\n') 1310 self.write_footer(out, short=True)
    1311
    1312 - def write_module_toc(self, out, doc):
    1313 """ 1314 Write an HTML page containing the table of contents page for 1315 the given module to the given streams. This page lists the 1316 modules, classes, exceptions, functions, and variables defined 1317 by the module. 1318 """ 1319 name = doc.canonical_name[-1] 1320 self.write_header(out, name) 1321 out('<h1 class="toc">Module %s</h1>\n' % name) 1322 out('<hr />\n') 1323 1324 1325 # List the classes. 1326 classes = doc.select_variables(value_type='class', imported=False, 1327 public=self._public_filter) 1328 self.write_toc_section(out, "Classes", classes, fullname=False) 1329 1330 # List the functions. 1331 funcs = doc.select_variables(value_type='function', imported=False, 1332 public=self._public_filter) 1333 self.write_toc_section(out, "Functions", funcs, fullname=False) 1334 1335 # List the variables. 1336 variables = doc.select_variables(value_type='other', imported=False, 1337 public=self._public_filter) 1338 self.write_toc_section(out, "Variables", variables, fullname=False) 1339 1340 # Footer material. 1341 out('<hr />\n') 1342 if self._show_private: 1343 out(self.PRIVATE_LINK+'\n') 1344 self.write_footer(out, short=True)
    1345 1346 #//////////////////////////////////////////////////////////// 1347 #{ 2.7. Project homepage (index.html) 1348 #//////////////////////////////////////////////////////////// 1349
    1350 - def write_homepage(self, directory):
    1351 """ 1352 Write an C{index.html} file in the given directory. The 1353 contents of this file are copied or linked from an existing 1354 page, so this method must be called after all pages have been 1355 written. The page used is determined by L{_frames_index} and 1356 L{_top_page}: 1357 - If L{_frames_index} is true, then C{frames.html} is 1358 copied. 1359 - Otherwise, the page specified by L{_top_page} is 1360 copied. 1361 """ 1362 filename = os.path.join(directory, 'index.html') 1363 if self._frames_index: top = 'frames.html' 1364 else: top = self._top_page_url 1365 1366 # Copy the non-frames index file from top, if it's internal. 1367 if top[:5] != 'http:' and '/' not in top: 1368 try: 1369 # Read top into `s`. 1370 topfile = os.path.join(directory, top) 1371 s = open(topfile, 'r').read() 1372 1373 # Write the output file. 1374 open(filename, 'w').write(s) 1375 return 1376 except: 1377 log.error('Warning: error copying index; ' 1378 'using a redirect page') 1379 1380 # Use a redirect if top is external, or if we faild to copy. 1381 name = self._prj_name or 'this project' 1382 f = open(filename, 'w') 1383 self.write_redirect_index(f.write, top, name) 1384 f.close()
    1385 1386 write_redirect_index = compile_template( 1387 """ 1388 write_redirect_index(self, out, top, name) 1389 """, 1390 # /------------------------- Template -------------------------\ 1391 ''' 1392 <?xml version="1.0" encoding="iso-8859-1"?> 1393 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 1394 "DTD/xhtml1-strict.dtd"> 1395 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 1396 <head> 1397 <title> Redirect </title> 1398 <meta http-equiv="refresh" content="1;url=$top$" /> 1399 <link rel="stylesheet" href="epydoc.css" type="text/css"></link> 1400 </head> 1401 <body> 1402 <p>Redirecting to the API documentation for 1403 <a href="$top$">$self._prj_name or "this project"$</a>...</p> 1404 </body> 1405 </html> 1406 ''') 1407 # \------------------------------------------------------------/ 1408 1409 #//////////////////////////////////////////////////////////// 1410 #{ 2.8. Stylesheet (epydoc.css) 1411 #//////////////////////////////////////////////////////////// 1412
    1413 - def write_css(self, directory, cssname):
    1414 """ 1415 Write the CSS stylesheet in the given directory. If 1416 C{cssname} contains a stylesheet file or name (from 1417 L{epydoc.docwriter.html_css}), then use that stylesheet; 1418 otherwise, use the default stylesheet. 1419 1420 @rtype: C{None} 1421 """ 1422 filename = os.path.join(directory, 'epydoc.css') 1423 1424 # Get the contents for the stylesheet file. 1425 if cssname is None: 1426 css = STYLESHEETS['default'][0] 1427 else: 1428 if os.path.exists(cssname): 1429 try: css = open(cssname).read() 1430 except: raise IOError("Can't open CSS file: %r" % cssname) 1431 elif cssname in STYLESHEETS: 1432 css = STYLESHEETS[cssname][0] 1433 else: 1434 raise IOError("Can't find CSS file: %r" % cssname) 1435 1436 # Write the stylesheet. 1437 cssfile = open(filename, 'w') 1438 cssfile.write(css) 1439 cssfile.close()
    1440 1441 #//////////////////////////////////////////////////////////// 1442 #{ 2.9. Javascript (epydoc.js) 1443 #//////////////////////////////////////////////////////////// 1444
    1445 - def write_javascript(self, directory):
    1446 jsfile = open(os.path.join(directory, 'epydoc.js'), 'w') 1447 print >> jsfile, self.TOGGLE_PRIVATE_JS 1448 print >> jsfile, self.SHOW_PRIVATE_JS 1449 print >> jsfile, self.GET_COOKIE_JS 1450 print >> jsfile, self.SET_FRAME_JS 1451 print >> jsfile, self.HIDE_PRIVATE_JS 1452 print >> jsfile, self.TOGGLE_CALLGRAPH_JS 1453 print >> jsfile, html_colorize.PYSRC_JAVASCRIPTS 1454 print >> jsfile, self.GET_ANCHOR_JS 1455 print >> jsfile, self.REDIRECT_URL_JS 1456 jsfile.close()
    1457 1458 #: A javascript that is used to show or hide the API documentation 1459 #: for private objects. In order for this to work correctly, all 1460 #: documentation for private objects should be enclosed in 1461 #: C{<div class="private">...</div>} elements. 1462 TOGGLE_PRIVATE_JS = ''' 1463 function toggle_private() { 1464 // Search for any private/public links on this page. Store 1465 // their old text in "cmd," so we will know what action to 1466 // take; and change their text to the opposite action. 1467 var cmd = "?"; 1468 var elts = document.getElementsByTagName("a"); 1469 for(var i=0; i<elts.length; i++) { 1470 if (elts[i].className == "privatelink") { 1471 cmd = elts[i].innerHTML; 1472 elts[i].innerHTML = ((cmd && cmd.substr(0,4)=="show")? 1473 "hide&nbsp;private":"show&nbsp;private"); 1474 } 1475 } 1476 // Update all DIVs containing private objects. 1477 var elts = document.getElementsByTagName("div"); 1478 for(var i=0; i<elts.length; i++) { 1479 if (elts[i].className == "private") { 1480 elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":"block"); 1481 } 1482 else if (elts[i].className == "public") { 1483 elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"block":"none"); 1484 } 1485 } 1486 // Update all table rows containing private objects. Note, we 1487 // use "" instead of "block" becaue IE & firefox disagree on what 1488 // this should be (block vs table-row), and "" just gives the 1489 // default for both browsers. 1490 var elts = document.getElementsByTagName("tr"); 1491 for(var i=0; i<elts.length; i++) { 1492 if (elts[i].className == "private") { 1493 elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":""); 1494 } 1495 } 1496 // Update all list items containing private objects. 1497 var elts = document.getElementsByTagName("li"); 1498 for(var i=0; i<elts.length; i++) { 1499 if (elts[i].className == "private") { 1500 elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")? 1501 "none":""); 1502 } 1503 } 1504 // Update all list items containing private objects. 1505 var elts = document.getElementsByTagName("ul"); 1506 for(var i=0; i<elts.length; i++) { 1507 if (elts[i].className == "private") { 1508 elts[i].style.display = ((cmd && cmd.substr(0,4)=="hide")?"none":"block"); 1509 } 1510 } 1511 // Set a cookie to remember the current option. 1512 document.cookie = "EpydocPrivate="+cmd; 1513 } 1514 '''.strip() 1515 1516 #: A javascript that is used to read the value of a cookie. This 1517 #: is used to remember whether private variables should be shown or 1518 #: hidden. 1519 GET_COOKIE_JS = ''' 1520 function getCookie(name) { 1521 var dc = document.cookie; 1522 var prefix = name + "="; 1523 var begin = dc.indexOf("; " + prefix); 1524 if (begin == -1) { 1525 begin = dc.indexOf(prefix); 1526 if (begin != 0) return null; 1527 } else 1528 { begin += 2; } 1529 var end = document.cookie.indexOf(";", begin); 1530 if (end == -1) 1531 { end = dc.length; } 1532 return unescape(dc.substring(begin + prefix.length, end)); 1533 } 1534 '''.strip() 1535 1536 #: A javascript that is used to set the contents of two frames at 1537 #: once. This is used by the project table-of-contents frame to 1538 #: set both the module table-of-contents frame and the main frame 1539 #: when the user clicks on a module. 1540 SET_FRAME_JS = ''' 1541 function setFrame(url1, url2) { 1542 parent.frames[1].location.href = url1; 1543 parent.frames[2].location.href = url2; 1544 } 1545 '''.strip() 1546 1547 #: A javascript that is used to hide private variables, unless 1548 #: either: (a) the cookie says not to; or (b) we appear to be 1549 #: linking to a private variable. 1550 HIDE_PRIVATE_JS = ''' 1551 function checkCookie() { 1552 var cmd=getCookie("EpydocPrivate"); 1553 if (cmd && cmd.substr(0,4)!="show" && location.href.indexOf("#_") < 0) 1554 toggle_private(); 1555 } 1556 '''.strip() 1557 1558 TOGGLE_CALLGRAPH_JS = ''' 1559 function toggleCallGraph(id) { 1560 var elt = document.getElementById(id); 1561 if (elt.style.display == "none") 1562 elt.style.display = "block"; 1563 else 1564 elt.style.display = "none"; 1565 } 1566 '''.strip() 1567 1568 SHOW_PRIVATE_JS = ''' 1569 function show_private() { 1570 var elts = document.getElementsByTagName("a"); 1571 for(var i=0; i<elts.length; i++) { 1572 if (elts[i].className == "privatelink") { 1573 cmd = elts[i].innerHTML; 1574 if (cmd && cmd.substr(0,4)=="show") 1575 toggle_private(); 1576 } 1577 } 1578 } 1579 '''.strip() 1580 1581 GET_ANCHOR_JS = ''' 1582 function get_anchor() { 1583 var href = location.href; 1584 var start = href.indexOf("#")+1; 1585 if ((start != 0) && (start != href.length)) 1586 return href.substring(start, href.length); 1587 } 1588 '''.strip() 1589 1590 #: A javascript that is used to implement the auto-redirect page. 1591 #: When the user visits <redirect.html#dotted.name>, they will 1592 #: automatically get redirected to the page for the object with 1593 #: the given fully-qualified dotted name. E.g., for epydoc, 1594 #: <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to 1595 #: <epydoc.apidoc-module.html#UNKNOWN>. 1596 REDIRECT_URL_JS = ''' 1597 function redirect_url(dottedName) { 1598 // Scan through each element of the "pages" list, and check 1599 // if "name" matches with any of them. 1600 for (var i=0; i<pages.length; i++) { 1601 1602 // Each page has the form "<pagename>-m" or "<pagename>-c"; 1603 // extract the <pagename> portion & compare it to dottedName. 1604 var pagename = pages[i].substring(0, pages[i].length-2); 1605 if (pagename == dottedName.substring(0,pagename.length)) { 1606 1607 // We\'ve found a page that matches `dottedName`; 1608 // construct its URL, using leftover `dottedName` 1609 // content to form an anchor. 1610 var pagetype = pages[i].charAt(pages[i].length-1); 1611 var url = pagename + ((pagetype=="m")?"-module.html": 1612 "-class.html"); 1613 if (dottedName.length > pagename.length) 1614 url += "#" + dottedName.substring(pagename.length+1, 1615 dottedName.length); 1616 return url; 1617 } 1618 } 1619 } 1620 '''.strip() 1621 1622 1623 #//////////////////////////////////////////////////////////// 1624 #{ 2.10. Graphs 1625 #//////////////////////////////////////////////////////////// 1626
    1627 - def render_graph(self, graph):
    1628 if graph is None: return '' 1629 graph.caption = graph.title = None 1630 image_url = '%s.gif' % graph.uid 1631 image_file = os.path.join(self._directory, image_url) 1632 return graph.to_html(image_file, image_url)
    1633 1634 RE_CALLGRAPH_ID = re.compile(r"""["'](.+-div)['"]""") 1635
    1636 - def render_callgraph(self, callgraph, token=""):
    1637 """Render the HTML chunk of a callgraph. 1638 1639 If C{callgraph} is a string, use the L{_callgraph_cache} to return 1640 a pre-rendered HTML chunk. This mostly avoids to run C{dot} twice for 1641 the same callgraph. Else, run the graph and store its HTML output in 1642 the cache. 1643 1644 @param callgraph: The graph to render or its L{uid<DotGraph.uid>}. 1645 @type callgraph: L{DotGraph} or C{str} 1646 @param token: A string that can be used to make the C{<div>} id 1647 unambiguous, if the callgraph is used more than once in a page. 1648 @type token: C{str} 1649 @return: The HTML representation of the graph. 1650 @rtype: C{str} 1651 """ 1652 if callgraph is None: return "" 1653 1654 if isinstance(callgraph, basestring): 1655 uid = callgraph 1656 rv = self._callgraph_cache.get(callgraph, "") 1657 1658 else: 1659 uid = callgraph.uid 1660 graph_html = self.render_graph(callgraph) 1661 if graph_html == '': 1662 rv = "" 1663 else: 1664 rv = ('<div style="display:none" id="%%s-div"><center>\n' 1665 '<table border="0" cellpadding="0" cellspacing="0">\n' 1666 ' <tr><td>%s</td></tr>\n' 1667 ' <tr><th>Call Graph</th></tr>\n' 1668 '</table><br />\n</center></div>\n' % graph_html) 1669 1670 # Store in the cache the complete HTML chunk without the 1671 # div id, which may be made unambiguous by the token 1672 self._callgraph_cache[uid] = rv 1673 1674 # Mangle with the graph 1675 if rv: rv = rv % (uid + token) 1676 return rv
    1677 1703 1704 #//////////////////////////////////////////////////////////// 1705 #{ 2.11. Images 1706 #//////////////////////////////////////////////////////////// 1707 1708 IMAGES = {'crarr.png': # Carriage-return arrow, used for LINEWRAP. 1709 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAMAAABlokWQAAAALHRFWHRD' 1710 'cmVhdGlvbiBUaW1lAFR1\nZSAyMiBBdWcgMjAwNiAwMDo0MzoxMCAtMD' 1711 'UwMGAMEFgAAAAHdElNRQfWCBYFASkQ033WAAAACXBI\nWXMAAB7CAAAe' 1712 'wgFu0HU+AAAABGdBTUEAALGPC/xhBQAAAEVQTFRF////zcOw18/AgGY0' 1713 'c1cg4dvQ\ninJEYEAAYkME3NXI6eTcloFYe2Asr5+AbE4Uh29A9fPwqp' 1714 'l4ZEUI8O3onopk0Ma0lH5U1nfFdgAA\nAAF0Uk5TAEDm2GYAAABNSURB' 1715 'VHjaY2BAAbzsvDAmK5oIlxgfioiwCAe7KJKIgKAQOzsLLwTwA0VY\n+d' 1716 'iRAT8T0AxuIIMHqoaXCWIPGzsHJ6orGJiYWRjQASOcBQAocgMSPKMTIg' 1717 'AAAABJRU5ErkJggg==\n', 1718 } 1719
    1720 - def write_images(self, directory):
    1721 for (name, data) in self.IMAGES.items(): 1722 f = open(os.path.join(directory, name), 'wb') 1723 f.write(base64.decodestring(data)) 1724 f.close()
    1725 1726 #//////////////////////////////////////////////////////////// 1727 #{ 3.1. Page Header 1728 #//////////////////////////////////////////////////////////// 1729 1730 write_header = compile_template( 1731 """ 1732 write_header(self, out, title) 1733 1734 Generate HTML code for the standard page header, and write it 1735 to C{out}. C{title} is a string containing the page title. 1736 It should be appropriately escaped/encoded. 1737 """, 1738 # /------------------------- Template -------------------------\ 1739 ''' 1740 <?xml version="1.0" encoding="ascii"?> 1741 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 1742 "DTD/xhtml1-transitional.dtd"> 1743 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 1744 <head> 1745 <title>$title$</title> 1746 <link rel="stylesheet" href="epydoc.css" type="text/css" /> 1747 <script type="text/javascript" src="epydoc.js"></script> 1748 </head> 1749 1750 <body bgcolor="white" text="black" link="blue" vlink="#204080" 1751 alink="#204080"> 1752 ''') 1753 # \------------------------------------------------------------/ 1754 1755 #//////////////////////////////////////////////////////////// 1756 #{ 3.2. Page Footer 1757 #//////////////////////////////////////////////////////////// 1758 1759 write_footer = compile_template( 1760 """ 1761 write_footer(self, out, short=False) 1762 1763 Generate HTML code for the standard page footer, and write it 1764 to C{out}. 1765 """, 1766 # /------------------------- Template -------------------------\ 1767 ''' 1768 >>> if not short: 1769 <table border="0" cellpadding="0" cellspacing="0" width="100%%"> 1770 <tr> 1771 <td align="left" class="footer"> 1772 >>> if self._include_log: 1773 <a href="epydoc-log.html">Generated by Epydoc 1774 $epydoc.__version__$ on $time.asctime()$</a> 1775 >>> else: 1776 Generated by Epydoc $epydoc.__version__$ on $time.asctime()$ 1777 >>> #endif 1778 </td> 1779 <td align="right" class="footer"> 1780 <a target="mainFrame" href="http://epydoc.sourceforge.net" 1781 >http://epydoc.sourceforge.net</a> 1782 </td> 1783 </tr> 1784 </table> 1785 >>> #endif 1786 1787 <script type="text/javascript"> 1788 <!-- 1789 // Private objects are initially displayed (because if 1790 // javascript is turned off then we want them to be 1791 // visible); but by default, we want to hide them. So hide 1792 // them unless we have a cookie that says to show them. 1793 checkCookie(); 1794 // --> 1795 </script> 1796 </body> 1797 </html> 1798 ''') 1799 # \------------------------------------------------------------/ 1800 1801 #//////////////////////////////////////////////////////////// 1802 #{ 3.3. Navigation Bar 1803 #//////////////////////////////////////////////////////////// 1804 1805 write_navbar = compile_template( 1806 """ 1807 write_navbar(self, out, context) 1808 1809 Generate HTML code for the navigation bar, and write it to 1810 C{out}. The navigation bar typically looks like:: 1811 1812 [ Home Trees Index Help Project ] 1813 1814 @param context: A value indicating what page we're generating 1815 a navigation bar for. If we're generating an API 1816 documentation page for an object, then C{context} is a 1817 L{ValueDoc} containing the documentation for that object; 1818 otherwise, C{context} is a string name for the page. The 1819 following string names are recognized: C{'tree'}, C{'index'}, 1820 and C{'help'}. 1821 """, 1822 # /------------------------- Template -------------------------\ 1823 ''' 1824 <!-- ==================== NAVIGATION BAR ==================== --> 1825 <table class="navbar" border="0" width="100%" cellpadding="0" 1826 bgcolor="#a0c0ff" cellspacing="0"> 1827 <tr valign="middle"> 1828 >>> if self._top_page_url not in (self._trees_url, "identifier-index.html", "help.html"): 1829 <!-- Home link --> 1830 >>> if (isinstance(context, ValueDoc) and 1831 >>> self._top_page_url == self.url(context.canonical_name)): 1832 <th bgcolor="#70b0f0" class="navbar-select" 1833 >&nbsp;&nbsp;&nbsp;Home&nbsp;&nbsp;&nbsp;</th> 1834 >>> else: 1835 <th>&nbsp;&nbsp;&nbsp;<a 1836 href="$self._top_page_url$">Home</a>&nbsp;&nbsp;&nbsp;</th> 1837 >>> #endif 1838 1839 <!-- Tree link --> 1840 >>> if context == "trees": 1841 <th bgcolor="#70b0f0" class="navbar-select" 1842 >&nbsp;&nbsp;&nbsp;Trees&nbsp;&nbsp;&nbsp;</th> 1843 >>> else: 1844 <th>&nbsp;&nbsp;&nbsp;<a 1845 href="$self._trees_url$">Trees</a>&nbsp;&nbsp;&nbsp;</th> 1846 >>> #endif 1847 1848 <!-- Index link --> 1849 >>> if context == "indices": 1850 <th bgcolor="#70b0f0" class="navbar-select" 1851 >&nbsp;&nbsp;&nbsp;Indices&nbsp;&nbsp;&nbsp;</th> 1852 >>> else: 1853 <th>&nbsp;&nbsp;&nbsp;<a 1854 href="identifier-index.html">Indices</a>&nbsp;&nbsp;&nbsp;</th> 1855 >>> #endif 1856 1857 <!-- Help link --> 1858 >>> if context == "help": 1859 <th bgcolor="#70b0f0" class="navbar-select" 1860 >&nbsp;&nbsp;&nbsp;Help&nbsp;&nbsp;&nbsp;</th> 1861 >>> else: 1862 <th>&nbsp;&nbsp;&nbsp;<a 1863 href="help.html">Help</a>&nbsp;&nbsp;&nbsp;</th> 1864 >>> #endif 1865 1866 >>> if self._prj_link: 1867 <!-- Project homepage --> 1868 <th class="navbar" align="right" width="100%"> 1869 <table border="0" cellpadding="0" cellspacing="0"> 1870 <tr><th class="navbar" align="center" 1871 >$self._prj_link.strip()$</th> 1872 </tr></table></th> 1873 >>> else: 1874 <th class="navbar" width="100%"></th> 1875 >>> #endif 1876 </tr> 1877 </table> 1878 ''') 1879 # \------------------------------------------------------------/ 1880 1881 #//////////////////////////////////////////////////////////// 1882 #{ 3.4. Breadcrumbs 1883 #//////////////////////////////////////////////////////////// 1884 1885 write_breadcrumbs = compile_template( 1886 """ 1887 write_breadcrumbs(self, out, context, context_url) 1888 1889 Generate HTML for the breadcrumbs line, and write it to 1890 C{out}. The breadcrumbs line is an invisible table with a 1891 list of pointers to the current object's ancestors on the 1892 left; and the show/hide private selector and the 1893 frames/noframes selector on the right. 1894 1895 @param context: The API documentation for the object whose 1896 breadcrumbs we should generate. 1897 @type context: L{ValueDoc} 1898 """, 1899 # /------------------------- Template -------------------------\ 1900 ''' 1901 <table width="100%" cellpadding="0" cellspacing="0"> 1902 <tr valign="top"> 1903 >>> if isinstance(context, APIDoc): 1904 <td width="100%"> 1905 <span class="breadcrumbs"> 1906 >>> crumbs = self.breadcrumbs(context) 1907 >>> for crumb in crumbs[:-1]: 1908 $crumb$ :: 1909 >>> #endfor 1910 $crumbs[-1]$ 1911 </span> 1912 </td> 1913 >>> else: 1914 <td width="100%">&nbsp;</td> 1915 >>> #endif 1916 <td> 1917 <table cellpadding="0" cellspacing="0"> 1918 <!-- hide/show private --> 1919 >>> if self._show_private: 1920 <tr><td align="right">$self.PRIVATE_LINK$</td></tr> 1921 >>> #endif 1922 >>> if self._frames_index: 1923 <tr><td align="right"><span class="options" 1924 >[<a href="frames.html" target="_top">frames</a 1925 >]&nbsp;|&nbsp;<a href="$context_url$" 1926 target="_top">no&nbsp;frames</a>]</span></td></tr> 1927 >>> #endif 1928 </table> 1929 </td> 1930 </tr> 1931 </table> 1932 ''') 1933 # \------------------------------------------------------------/ 1934
    1935 - def breadcrumbs(self, doc):
    1936 crumbs = [self._crumb(doc)] 1937 1938 # Generate the crumbs for uid's ancestors. 1939 while True: 1940 container = self.docindex.container(doc) 1941 assert doc != container, 'object is its own container?' 1942 if container is None: 1943 if doc.canonical_name is UNKNOWN: 1944 return ['??']+crumbs 1945 elif isinstance(doc, ModuleDoc): 1946 return ['Package&nbsp;%s' % ident 1947 for ident in doc.canonical_name[:-1]]+crumbs 1948 else: 1949 return list(doc.canonical_name)+crumbs 1950 else: 1951 label = self._crumb(container) 1952 name = container.canonical_name 1953 crumbs.insert(0, self.href(container, label)) # [xx] code=0?? 1954 doc = container
    1955
    1956 - def _crumb(self, doc):
    1957 if (len(doc.canonical_name)==1 and 1958 doc.canonical_name[0].startswith('script-')): 1959 return 'Script&nbsp;%s' % doc.canonical_name[0][7:] 1960 return '%s&nbsp;%s' % (self.doc_kind(doc), doc.canonical_name[-1])
    1961 1962 #//////////////////////////////////////////////////////////// 1963 #{ 3.5. Summary Tables 1964 #//////////////////////////////////////////////////////////// 1965
    1966 - def write_summary_table(self, out, heading, doc, value_type):
    1967 """ 1968 Generate HTML code for a summary table, and write it to 1969 C{out}. A summary table is a table that includes a one-row 1970 description for each variable (of a given type) in a module 1971 or class. 1972 1973 @param heading: The heading for the summary table; typically, 1974 this indicates what kind of value the table describes 1975 (e.g., functions or classes). 1976 @param doc: A L{ValueDoc} object containing the API 1977 documentation for the module or class whose variables 1978 we should summarize. 1979 @param value_type: A string indicating what type of value 1980 should be listed in this summary table. This value 1981 is passed on to C{doc}'s C{select_variables()} method. 1982 """ 1983 # inh_var_groups is a dictionary used to hold "inheritance 1984 # pseudo-groups", which are created when inheritance is 1985 # 'grouped'. It maps each base to a list of vars inherited 1986 # from that base. 1987 grouped_inh_vars = {} 1988 1989 # Divide all public variables of the given type into groups. 1990 groups = [(plaintext_to_html(group_name), 1991 doc.select_variables(group=group_name, imported=False, 1992 value_type=value_type, 1993 public=self._public_filter)) 1994 for group_name in doc.group_names()] 1995 1996 # Discard any empty groups; and return if they're all empty. 1997 groups = [(g,vars) for (g,vars) in groups if vars] 1998 if not groups: return 1999 2000 # Write a header 2001 self.write_table_header(out, "summary", heading) 2002 2003 # Write a section for each group. 2004 for name, var_docs in groups: 2005 self.write_summary_group(out, doc, name, 2006 var_docs, grouped_inh_vars) 2007 2008 # Write a section for each inheritance pseudo-group (used if 2009 # inheritance=='grouped') 2010 if grouped_inh_vars: 2011 for base in doc.mro(): 2012 if base in grouped_inh_vars: 2013 hdr = 'Inherited from %s' % self.href(base, context=doc) 2014 tr_class = '' 2015 if len([v for v in grouped_inh_vars[base] 2016 if v.is_public]) == 0: 2017 tr_class = ' class="private"' 2018 self.write_group_header(out, hdr, tr_class) 2019 for var_doc in grouped_inh_vars[base]: 2020 self.write_summary_line(out, var_doc, doc) 2021 2022 # Write a footer for the table. 2023 out(self.TABLE_FOOTER)
    2024
    2025 - def write_summary_group(self, out, doc, name, var_docs, grouped_inh_vars):
    2026 # Split up the var_docs list, according to the way each var 2027 # should be displayed: 2028 # - listed_inh_vars -- for listed inherited variables. 2029 # - grouped_inh_vars -- for grouped inherited variables. 2030 # - normal_vars -- for all other variables. 2031 listed_inh_vars = {} 2032 normal_vars = [] 2033 for var_doc in var_docs: 2034 if var_doc.container != doc: 2035 base = var_doc.container 2036 if not isinstance(base, ClassDoc): 2037 # This *should* never happen: 2038 log.warning("%s's container is not a class!" % var_doc) 2039 normal_vars.append(var_doc) 2040 elif (base not in self.class_set or 2041 self._inheritance == 'listed'): 2042 listed_inh_vars.setdefault(base,[]).append(var_doc) 2043 elif self._inheritance == 'grouped': 2044 grouped_inh_vars.setdefault(base,[]).append(var_doc) 2045 else: 2046 normal_vars.append(var_doc) 2047 else: 2048 normal_vars.append(var_doc) 2049 2050 # Write a header for the group. 2051 if name != '': 2052 tr_class = '' 2053 if len([v for v in var_docs if v.is_public]) == 0: 2054 tr_class = ' class="private"' 2055 self.write_group_header(out, name, tr_class) 2056 2057 # Write a line for each normal var: 2058 for var_doc in normal_vars: 2059 self.write_summary_line(out, var_doc, doc) 2060 # Write a subsection for inherited vars: 2061 if listed_inh_vars: 2062 self.write_inheritance_list(out, doc, listed_inh_vars)
    2063
    2064 - def write_inheritance_list(self, out, doc, listed_inh_vars):
    2065 out(' <tr>\n <td colspan="2" class="summary">\n') 2066 for base in doc.mro(): 2067 if base not in listed_inh_vars: continue 2068 public_vars = [v for v in listed_inh_vars[base] 2069 if v.is_public] 2070 private_vars = [v for v in listed_inh_vars[base] 2071 if not v.is_public] 2072 if public_vars: 2073 out(' <p class="indent-wrapped-lines">' 2074 '<b>Inherited from <code>%s</code></b>:\n' % 2075 self.href(base, context=doc)) 2076 self.write_var_list(out, public_vars) 2077 out(' </p>\n') 2078 if private_vars and self._show_private: 2079 out(' <div class="private">') 2080 out(' <p class="indent-wrapped-lines">' 2081 '<b>Inherited from <code>%s</code></b> (private):\n' % 2082 self.href(base, context=doc)) 2083 self.write_var_list(out, private_vars) 2084 out(' </p></div>\n') 2085 out(' </td>\n </tr>\n')
    2086
    2087 - def write_var_list(self, out, vardocs):
    2088 out(' ') 2089 out(',\n '.join(['<code>%s</code>' % self.href(v,v.name) 2090 for v in vardocs])+'\n')
    2091
    2092 - def write_summary_line(self, out, var_doc, container):
    2093 """ 2094 Generate HTML code for a single line of a summary table, and 2095 write it to C{out}. See L{write_summary_table} for more 2096 information. 2097 2098 @param var_doc: The API documentation for the variable that 2099 should be described by this line of the summary table. 2100 @param container: The API documentation for the class or 2101 module whose summary table we're writing. 2102 """ 2103 pysrc_link = None 2104 callgraph = None 2105 2106 # If it's a private variable, then mark its <tr>. 2107 if var_doc.is_public: tr_class = '' 2108 else: tr_class = ' class="private"' 2109 2110 # Decide an anchor or a link is to be generated. 2111 link_name = self._redundant_details or var_doc.is_detailed() 2112 anchor = not link_name 2113 2114 # Construct the HTML code for the type (cell 1) & description 2115 # (cell 2). 2116 if isinstance(var_doc.value, RoutineDoc): 2117 typ = self.return_type(var_doc, indent=6) 2118 description = self.function_signature(var_doc, is_summary=True, 2119 link_name=link_name, anchor=anchor) 2120 pysrc_link = self.pysrc_link(var_doc.value) 2121 2122 # Perpare the call-graph, if requested 2123 if 'callgraph' in self._graph_types: 2124 linker = _HTMLDocstringLinker(self, var_doc.value) 2125 callgraph = call_graph([var_doc.value], self.docindex, 2126 linker, var_doc, add_callers=True, 2127 add_callees=True) 2128 if callgraph and callgraph.nodes: 2129 var_doc.value.callgraph_uid = callgraph.uid 2130 else: 2131 callgraph = None 2132 else: 2133 typ = self.type_descr(var_doc, indent=6) 2134 description = self.summary_name(var_doc, 2135 link_name=link_name, anchor=anchor) 2136 if isinstance(var_doc.value, GenericValueDoc): 2137 # The summary max length has been chosen setting 2138 # L{ValueDoc.SUMMARY_REPR_LINELEN} in the constructor 2139 max_len=self._variable_summary_linelen-3-len(var_doc.name) 2140 val_repr = var_doc.value.summary_pyval_repr(max_len) 2141 tooltip = self.variable_tooltip(var_doc) 2142 description += (' = <code%s>%s</code>' % 2143 (tooltip, val_repr.to_html(None))) 2144 2145 # Add the summary to the description (if there is one). 2146 summary = self.summary(var_doc, indent=6) 2147 if summary: description += '<br />\n %s' % summary 2148 2149 # If it's inherited, then add a note to the description. 2150 if var_doc.container != container and self._inheritance=="included": 2151 description += ("\n <em>(Inherited from " + 2152 self.href(var_doc.container) + ")</em>") 2153 2154 # Write the summary line. 2155 self._write_summary_line(out, typ, description, tr_class, pysrc_link, 2156 callgraph)
    2157 2158 _write_summary_line = compile_template( 2159 "_write_summary_line(self, out, typ, description, tr_class, " 2160 "pysrc_link, callgraph)", 2161 # /------------------------- Template -------------------------\ 2162 ''' 2163 <tr$tr_class$> 2164 <td width="15%" align="right" valign="top" class="summary"> 2165 <span class="summary-type">$typ or "&nbsp;"$</span> 2166 </td><td class="summary"> 2167 >>> if pysrc_link is not None or callgraph is not None: 2168 <table width="100%" cellpadding="0" cellspacing="0" border="0"> 2169 <tr> 2170 <td>$description$</td> 2171 <td align="right" valign="top"> 2172 $pysrc_link$ 2173 $self.callgraph_link(callgraph, token='-summary')$ 2174 </td> 2175 </tr> 2176 </table> 2177 $self.render_callgraph(callgraph, token='-summary')$ 2178 >>> #endif 2179 >>> if pysrc_link is None and callgraph is None: 2180 $description$ 2181 >>> #endif 2182 </td> 2183 </tr> 2184 ''') 2185 # \------------------------------------------------------------/ 2186 2187 #//////////////////////////////////////////////////////////// 2188 #{ 3.6. Details Lists 2189 #//////////////////////////////////////////////////////////// 2190
    2191 - def write_details_list(self, out, heading, doc, value_type):
    2192 # Get a list of the VarDocs we should describe. 2193 if self._redundant_details: 2194 detailed = None 2195 else: 2196 detailed = True 2197 if isinstance(doc, ClassDoc): 2198 var_docs = doc.select_variables(value_type=value_type, 2199 imported=False, inherited=False, 2200 public=self._public_filter, 2201 detailed=detailed) 2202 else: 2203 var_docs = doc.select_variables(value_type=value_type, 2204 imported=False, 2205 public=self._public_filter, 2206 detailed=detailed) 2207 if not var_docs: return 2208 2209 # Write a header 2210 self.write_table_header(out, "details", heading) 2211 out(self.TABLE_FOOTER) 2212 2213 for var_doc in var_docs: 2214 self.write_details_entry(out, var_doc) 2215 2216 out('<br />\n')
    2217
    2218 - def write_details_entry(self, out, var_doc):
    2219 descr = self.descr(var_doc, indent=2) or '' 2220 if var_doc.is_public: div_class = '' 2221 else: div_class = ' class="private"' 2222 2223 # Functions 2224 if isinstance(var_doc.value, RoutineDoc): 2225 rtype = self.return_type(var_doc, indent=10) 2226 rdescr = self.return_descr(var_doc, indent=10) 2227 arg_descrs = [] 2228 args = set() 2229 # Find the description for each arg. (Leave them in the 2230 # same order that they're listed in the docstring.) 2231 for (arg_names, arg_descr) in var_doc.value.arg_descrs: 2232 args.update(arg_names) 2233 lhs = ', '.join([self.arg_name_to_html(var_doc.value, n) 2234 for n in arg_names]) 2235 rhs = self.docstring_to_html(arg_descr, var_doc.value, 10) 2236 arg_descrs.append( (lhs, rhs) ) 2237 # Check for arguments for which we have @type but not @param; 2238 # and add them to the arg_descrs list. 2239 for arg in var_doc.value.arg_types: 2240 if arg not in args: 2241 argname = self.arg_name_to_html(var_doc.value, arg) 2242 arg_descrs.append( (argname,'') ) 2243 2244 self.write_function_details_entry(out, var_doc, descr, 2245 var_doc.value.callgraph_uid, 2246 rtype, rdescr, arg_descrs, 2247 div_class) 2248 2249 # Properties 2250 elif isinstance(var_doc.value, PropertyDoc): 2251 prop_doc = var_doc.value 2252 accessors = [ (name, 2253 self.property_accessor_to_html(val_doc, prop_doc), 2254 self.summary(val_doc)) 2255 for (name, val_doc) in 2256 [('Get', prop_doc.fget), ('Set', prop_doc.fset), 2257 ('Delete', prop_doc.fdel)] 2258 if val_doc not in (None, UNKNOWN) 2259 and val_doc.pyval is not None ] 2260 2261 self.write_property_details_entry(out, var_doc, descr, 2262 accessors, div_class) 2263 2264 # Variables 2265 else: 2266 self.write_variable_details_entry(out, var_doc, descr, div_class)
    2267
    2268 - def labelled_list_item(self, lhs, rhs):
    2269 # If the RHS starts with a paragraph, then move the 2270 # paragraph-start tag to the beginning of the lhs instead (so 2271 # there won't be a line break after the '-'). 2272 m = re.match(r'^<p( [^>]+)?>', rhs) 2273 if m: 2274 lhs = m.group() + lhs 2275 rhs = rhs[m.end():] 2276 2277 if rhs: 2278 return '<li>%s - %s</li>' % (lhs, rhs) 2279 else: 2280 return '<li>%s</li>' % (lhs,)
    2281
    2282 - def property_accessor_to_html(self, val_doc, context=None):
    2283 if val_doc not in (None, UNKNOWN): 2284 if isinstance(val_doc, RoutineDoc): 2285 return self.function_signature(val_doc, is_summary=True, 2286 link_name=True, context=context) 2287 elif isinstance(val_doc, GenericValueDoc): 2288 return self.pprint_value(val_doc) 2289 else: 2290 return self.href(val_doc, context=context) 2291 else: 2292 return '??'
    2293
    2294 - def arg_name_to_html(self, func_doc, arg_name):
    2295 """ 2296 A helper function used to format an argument name, for use in 2297 the argument description list under a routine's details entry. 2298 This just wraps strong & code tags around the arg name; and if 2299 the arg name is associated with a type, then adds it 2300 parenthetically after the name. 2301 """ 2302 s = '<strong class="pname"><code>%s</code></strong>' % arg_name 2303 if arg_name in func_doc.arg_types: 2304 typ = func_doc.arg_types[arg_name] 2305 typ_html = self.docstring_to_html(typ, func_doc, 10) 2306 s += " (%s)" % typ_html 2307 return s
    2308 2309 write_function_details_entry = compile_template( 2310 ''' 2311 write_function_details_entry(self, out, var_doc, descr, callgraph, \ 2312 rtype, rdescr, arg_descrs, div_class) 2313 ''', 2314 # /------------------------- Template -------------------------\ 2315 ''' 2316 >>> func_doc = var_doc.value 2317 <a name="$var_doc.name$"></a> 2318 <div$div_class$> 2319 >>> self.write_table_header(out, "details") 2320 <tr><td> 2321 <table width="100%" cellpadding="0" cellspacing="0" border="0"> 2322 <tr valign="top"><td> 2323 <h3 class="epydoc">$self.function_signature(var_doc)$ 2324 >>> if var_doc.name in self.SPECIAL_METHODS: 2325 <br /><em class="fname">($self.SPECIAL_METHODS[var_doc.name]$)</em> 2326 >>> #endif 2327 >>> if isinstance(func_doc, ClassMethodDoc): 2328 <br /><em class="fname">Class Method</em> 2329 >>> #endif 2330 >>> if isinstance(func_doc, StaticMethodDoc): 2331 <br /><em class="fname">Static Method</em> 2332 >>> #endif 2333 </h3> 2334 </td><td align="right" valign="top" 2335 >$self.pysrc_link(func_doc)$&nbsp; 2336 $self.callgraph_link(callgraph)$</td> 2337 </tr></table> 2338 $self.render_callgraph(callgraph)$ 2339 $descr$ 2340 <dl class="fields"> 2341 >>> # === parameters === 2342 >>> if arg_descrs: 2343 <dt>Parameters:</dt> 2344 <dd><ul class="nomargin-top"> 2345 >>> for lhs, rhs in arg_descrs: 2346 $self.labelled_list_item(lhs, rhs)$ 2347 >>> #endfor 2348 </ul></dd> 2349 >>> #endif 2350 >>> # === return type === 2351 >>> if rdescr and rtype: 2352 <dt>Returns: $rtype$</dt> 2353 <dd>$rdescr$</dd> 2354 >>> elif rdescr: 2355 <dt>Returns:</dt> 2356 <dd>$rdescr$</dd> 2357 >>> elif rtype: 2358 <dt>Returns: $rtype$</dt> 2359 >>> #endif 2360 >>> # === decorators === 2361 >>> if func_doc.decorators not in (None, UNKNOWN): 2362 >>> # (staticmethod & classmethod are already shown, above) 2363 >>> decos = filter(lambda deco: 2364 >>> not ((deco=="staticmethod" and 2365 >>> isinstance(func_doc, StaticMethodDoc)) or 2366 >>> (deco=="classmethod" and 2367 >>> isinstance(func_doc, ClassMethodDoc))), 2368 >>> func_doc.decorators) 2369 >>> else: 2370 >>> decos = None 2371 >>> #endif 2372 >>> if decos: 2373 <dt>Decorators:</dt> 2374 <dd><ul class="nomargin-top"> 2375 >>> for deco in decos: 2376 <li><code>@$deco$</code></li> 2377 >>> #endfor 2378 </ul></dd> 2379 >>> #endif 2380 >>> # === exceptions === 2381 >>> if func_doc.exception_descrs not in (None, UNKNOWN, (), []): 2382 <dt>Raises:</dt> 2383 <dd><ul class="nomargin-top"> 2384 >>> for name, descr in func_doc.exception_descrs: 2385 >>> exc_name = self.docindex.find(name, func_doc) 2386 >>> if exc_name is not None: 2387 >>> name = self.href(exc_name, label=str(name)) 2388 >>> #endif 2389 $self.labelled_list_item( 2390 "<code><strong class=\'fraise\'>" + 2391 str(name) + "</strong></code>", 2392 self.docstring_to_html(descr, func_doc, 8))$ 2393 >>> #endfor 2394 </ul></dd> 2395 >>> #endif 2396 >>> # === overrides === 2397 >>> if var_doc.overrides not in (None, UNKNOWN): 2398 <dt>Overrides: 2399 >>> # Avoid passing GenericValueDoc to href() 2400 >>> if isinstance(var_doc.overrides.value, RoutineDoc): 2401 $self.href(var_doc.overrides.value, context=var_doc)$ 2402 >>> else: 2403 >>> # In this case, a less interesting label is generated. 2404 $self.href(var_doc.overrides, context=var_doc)$ 2405 >>> #endif 2406 >>> if (func_doc.docstring in (None, UNKNOWN) and 2407 >>> var_doc.overrides.value.docstring not in (None, UNKNOWN)): 2408 <dd><em class="note">(inherited documentation)</em></dd> 2409 >>> #endif 2410 </dt> 2411 >>> #endif 2412 </dl> 2413 >>> # === metadata === 2414 >>> self.write_standard_fields(out, func_doc) 2415 </td></tr></table> 2416 </div> 2417 ''') 2418 # \------------------------------------------------------------/ 2419 2420 # Names for the __special__ methods. 2421 SPECIAL_METHODS ={ 2422 '__init__': 'Constructor', 2423 '__del__': 'Destructor', 2424 '__add__': 'Addition operator', 2425 '__sub__': 'Subtraction operator', 2426 '__and__': 'And operator', 2427 '__or__': 'Or operator', 2428 '__xor__': 'Exclusive-Or operator', 2429 '__repr__': 'Representation operator', 2430 '__call__': 'Call operator', 2431 '__getattr__': 'Qualification operator', 2432 '__getitem__': 'Indexing operator', 2433 '__setitem__': 'Index assignment operator', 2434 '__delitem__': 'Index deletion operator', 2435 '__delslice__': 'Slice deletion operator', 2436 '__setslice__': 'Slice assignment operator', 2437 '__getslice__': 'Slicling operator', 2438 '__len__': 'Length operator', 2439 '__cmp__': 'Comparison operator', 2440 '__eq__': 'Equality operator', 2441 '__in__': 'Containership operator', 2442 '__gt__': 'Greater-than operator', 2443 '__lt__': 'Less-than operator', 2444 '__ge__': 'Greater-than-or-equals operator', 2445 '__le__': 'Less-than-or-equals operator', 2446 '__radd__': 'Right-side addition operator', 2447 '__hash__': 'Hashing function', 2448 '__contains__': 'In operator', 2449 '__nonzero__': 'Boolean test operator', 2450 '__str__': 'Informal representation operator', 2451 } 2452 2453 write_property_details_entry = compile_template( 2454 ''' 2455 write_property_details_entry(self, out, var_doc, descr, \ 2456 accessors, div_class) 2457 ''', 2458 # /------------------------- Template -------------------------\ 2459 ''' 2460 >>> prop_doc = var_doc.value 2461 <a name="$var_doc.name$"></a> 2462 <div$div_class$> 2463 >>> self.write_table_header(out, "details") 2464 <tr><td> 2465 <h3 class="epydoc">$var_doc.name$</h3> 2466 $descr$ 2467 <dl class="fields"> 2468 >>> for (name, val, summary) in accessors: 2469 <dt>$name$ Method:</dt> 2470 <dd class="value">$val$ 2471 >>> if summary: 2472 - $summary$ 2473 >>> #endif 2474 </dd> 2475 >>> #endfor 2476 >>> if prop_doc.type_descr not in (None, UNKNOWN): 2477 <dt>Type:</dt> 2478 <dd>$self.type_descr(var_doc, indent=6)$</dd> 2479 >>> #endif 2480 </dl> 2481 >>> self.write_standard_fields(out, prop_doc) 2482 </td></tr></table> 2483 </div> 2484 ''') 2485 # \------------------------------------------------------------/ 2486 2487 write_variable_details_entry = compile_template( 2488 ''' 2489 write_variable_details_entry(self, out, var_doc, descr, div_class) 2490 ''', 2491 # /------------------------- Template -------------------------\ 2492 ''' 2493 <a name="$var_doc.name$"></a> 2494 <div$div_class$> 2495 >>> self.write_table_header(out, "details") 2496 <tr><td> 2497 <h3 class="epydoc">$var_doc.name$</h3> 2498 $descr$ 2499 <dl class="fields"> 2500 >>> if var_doc.type_descr not in (None, UNKNOWN): 2501 <dt>Type:</dt> 2502 <dd>$self.type_descr(var_doc, indent=6)$</dd> 2503 >>> #endif 2504 </dl> 2505 >>> self.write_standard_fields(out, var_doc) 2506 >>> if var_doc.value is not UNKNOWN: 2507 <dl class="fields"> 2508 <dt>Value:</dt> 2509 <dd>$self.pprint_value(var_doc.value)$</dd> 2510 </dl> 2511 >>> #endif 2512 </td></tr></table> 2513 </div> 2514 ''') 2515 # \------------------------------------------------------------/ 2516
    2517 - def variable_tooltip(self, var_doc):
    2518 if var_doc.value in (None, UNKNOWN): 2519 return '' 2520 s = var_doc.value.pyval_repr().to_plaintext(None) 2521 if len(s) > self._variable_tooltip_linelen: 2522 s = s[:self._variable_tooltip_linelen-3]+'...' 2523 return ' title="%s"' % plaintext_to_html(s)
    2524
    2525 - def pprint_value(self, val_doc):
    2526 if val_doc is UNKNOWN: 2527 return '??' 2528 elif isinstance(val_doc, GenericValueDoc): 2529 return ('<table><tr><td><pre class="variable">\n' + 2530 val_doc.pyval_repr().to_html(None) + 2531 '\n</pre></td></tr></table>\n') 2532 else: 2533 return self.href(val_doc)
    2534 2535 #//////////////////////////////////////////////////////////// 2536 #{ Base Tree 2537 #//////////////////////////////////////////////////////////// 2538
    2539 - def base_tree(self, doc, width=None, postfix='', context=None):
    2540 """ 2541 @return: The HTML code for a class's base tree. The tree is 2542 drawn 'upside-down' and right justified, to allow for 2543 multiple inheritance. 2544 @rtype: C{string} 2545 """ 2546 if context is None: 2547 context = doc.defining_module 2548 if width == None: width = self.find_tree_width(doc, context) 2549 if isinstance(doc, ClassDoc) and doc.bases != UNKNOWN: 2550 bases = doc.bases 2551 else: 2552 bases = [] 2553 2554 if postfix == '': 2555 # [XX] use var name instead of canonical name? 2556 s = (' '*(width-2) + '<strong class="uidshort">'+ 2557 self.contextual_label(doc, context)+'</strong>\n') 2558 else: s = '' 2559 for i in range(len(bases)-1, -1, -1): 2560 base = bases[i] 2561 label = self.contextual_label(base, context) 2562 s = (' '*(width-4-len(label)) + self.href(base, label) 2563 +' --+'+postfix+'\n' + 2564 ' '*(width-4) + 2565 ' |'+postfix+'\n' + 2566 s) 2567 if i != 0: 2568 s = (self.base_tree(base, width-4, ' |'+postfix, context)+s) 2569 else: 2570 s = (self.base_tree(base, width-4, ' '+postfix, context)+s) 2571 return s
    2572
    2573 - def find_tree_width(self, doc, context):
    2574 """ 2575 Helper function for L{base_tree}. 2576 @return: The width of a base tree, when drawn 2577 right-justified. This is used by L{base_tree} to 2578 determine how far to indent lines of the base tree. 2579 @rtype: C{int} 2580 """ 2581 if not isinstance(doc, ClassDoc): return 2 2582 if doc.bases == UNKNOWN: return 2 2583 width = 2 2584 for base in doc.bases: 2585 width = max(width, len(self.contextual_label(base, context))+4, 2586 self.find_tree_width(base, context)+4) 2587 return width
    2588
    2589 - def contextual_label(self, doc, context):
    2590 """ 2591 Return the label for C{doc} to be shown in C{context}. 2592 """ 2593 if doc.canonical_name is None: 2594 if doc.parse_repr is not None: 2595 return doc.parse_repr 2596 else: 2597 return '??' 2598 else: 2599 if context is UNKNOWN: 2600 return str(doc.canonical_name) 2601 else: 2602 context_name = context.canonical_name 2603 return str(doc.canonical_name.contextualize(context_name))
    2604 2605 #//////////////////////////////////////////////////////////// 2606 #{ Function Signatures 2607 #//////////////////////////////////////////////////////////// 2608
    2609 - def function_signature(self, api_doc, is_summary=False, 2610 link_name=False, anchor=False, context=None):
    2611 """Render a function signature in HTML. 2612 2613 @param api_doc: The object whose name is to be rendered. If a 2614 C{VariableDoc}, its C{value} should be a C{RoutineDoc} 2615 @type api_doc: L{VariableDoc} or L{RoutineDoc} 2616 @param is_summary: True if the fuction is to be rendered in the summary. 2617 type css_class: C{bool} 2618 @param link_name: If True, the name is a link to the object anchor. 2619 @type link_name: C{bool} 2620 @param anchor: If True, the name is the object anchor. 2621 @type anchor: C{bool} 2622 @param context: If set, represent the function name from this context. 2623 Only useful when C{api_doc} is a L{RoutineDoc}. 2624 @type context: L{DottedName} 2625 2626 @return: The HTML code for the object. 2627 @rtype: C{str} 2628 """ 2629 if is_summary: css_class = 'summary-sig' 2630 else: css_class = 'sig' 2631 2632 # [XX] clean this up! 2633 if isinstance(api_doc, VariableDoc): 2634 func_doc = api_doc.value 2635 # This should never happen, but just in case: 2636 if api_doc.value in (None, UNKNOWN): 2637 return (('<span class="%s"><span class="%s-name">%s'+ 2638 '</span>(...)</span>') % 2639 (css_class, css_class, api_doc.name)) 2640 # Get the function's name. 2641 name = self.summary_name(api_doc, css_class=css_class+'-name', 2642 link_name=link_name, anchor=anchor) 2643 else: 2644 func_doc = api_doc 2645 name = self.href(api_doc, css_class=css_class+'-name', 2646 context=context) 2647 2648 if func_doc.posargs == UNKNOWN: 2649 args = ['...'] 2650 else: 2651 args = [self.func_arg(n, d, css_class) for (n, d) 2652 in zip(func_doc.posargs, func_doc.posarg_defaults)] 2653 if func_doc.vararg not in (None, UNKNOWN): 2654 if func_doc.vararg == '...': 2655 args.append('<span class="%s-arg">...</span>' % css_class) 2656 else: 2657 args.append('<span class="%s-arg">*%s</span>' % 2658 (css_class, func_doc.vararg)) 2659 if func_doc.kwarg not in (None, UNKNOWN): 2660 args.append('<span class="%s-arg">**%s</span>' % 2661 (css_class, func_doc.kwarg)) 2662 2663 return ('<span class="%s">%s(%s)</span>' % 2664 (css_class, name, ',\n '.join(args)))
    2665
    2666 - def summary_name(self, api_doc, css_class='summary-name', 2667 link_name=False, anchor=False):
    2668 """Render an object name in HTML. 2669 2670 @param api_doc: The object whose name is to be rendered 2671 @type api_doc: L{APIDoc} 2672 @param css_class: The CSS class to assign to the rendered name 2673 type css_class: C{str} 2674 @param link_name: If True, the name is a link to the object anchor. 2675 @type link_name: C{bool} 2676 @param anchor: If True, the name is the object anchor. 2677 @type anchor: C{bool} 2678 2679 @return: The HTML code for the object. 2680 @rtype: C{str} 2681 """ 2682 if anchor: 2683 rv = '<a name="%s"></a>' % api_doc.name 2684 else: 2685 rv = '' 2686 2687 if link_name: 2688 rv += self.href(api_doc, css_class=css_class) 2689 else: 2690 rv += '<span class="%s">%s</span>' % (css_class, api_doc.name) 2691 2692 return rv
    2693 2694 # [xx] tuple args???
    2695 - def func_arg(self, name, default, css_class):
    2696 name = self._arg_name(name) 2697 s = '<span class="%s-arg">%s</span>' % (css_class, name) 2698 if default is not None: 2699 s += ('=<span class="%s-default">%s</span>' % 2700 (css_class, default.summary_pyval_repr().to_html(None))) 2701 return s
    2702
    2703 - def _arg_name(self, arg):
    2704 if isinstance(arg, basestring): 2705 return arg 2706 elif len(arg) == 1: 2707 return '(%s,)' % self._arg_name(arg[0]) 2708 else: 2709 return '(%s)' % (', '.join([self._arg_name(a) for a in arg]))
    2710 2711 2712 2713 2714 #//////////////////////////////////////////////////////////// 2715 #{ Import Lists 2716 #//////////////////////////////////////////////////////////// 2717
    2718 - def write_imports(self, out, doc):
    2719 assert isinstance(doc, NamespaceDoc) 2720 imports = doc.select_variables(imported=True, 2721 public=self._public_filter) 2722 if not imports: return 2723 2724 out('<p class="indent-wrapped-lines">') 2725 out('<b>Imports:</b>\n ') 2726 out(',\n '.join([self._import(v, doc) for v in imports])) 2727 out('\n</p><br />\n')
    2728
    2729 - def _import(self, var_doc, context):
    2730 if var_doc.imported_from not in (None, UNKNOWN): 2731 return self.href(var_doc.imported_from, 2732 var_doc.name, context=context, 2733 tooltip='%s' % var_doc.imported_from) 2734 elif (var_doc.value not in (None, UNKNOWN) and not 2735 isinstance(var_doc.value, GenericValueDoc)): 2736 return self.href(var_doc.value, 2737 var_doc.name, context=context, 2738 tooltip='%s' % var_doc.value.canonical_name) 2739 else: 2740 return plaintext_to_html(var_doc.name)
    2741 2742 #//////////////////////////////////////////////////////////// 2743 #{ Function Attributes 2744 #//////////////////////////////////////////////////////////// 2745 2746 #//////////////////////////////////////////////////////////// 2747 #{ Module Trees 2748 #//////////////////////////////////////////////////////////// 2749
    2750 - def write_module_list(self, out, doc):
    2751 if len(doc.submodules) == 0: return 2752 self.write_table_header(out, "summary", "Submodules") 2753 2754 for group_name in doc.group_names(): 2755 if not doc.submodule_groups[group_name]: continue 2756 if group_name: 2757 self.write_group_header(out, group_name) 2758 out(' <tr><td class="summary">\n' 2759 ' <ul class="nomargin">\n') 2760 for submodule in doc.submodule_groups[group_name]: 2761 self.write_module_tree_item(out, submodule, package=doc) 2762 out(' </ul></td></tr>\n') 2763 2764 out(self.TABLE_FOOTER+'\n<br />\n')
    2765
    2766 - def write_module_tree_item(self, out, doc, package=None):
    2767 # If it's a private variable, then mark its <li>. 2768 var = package and package.variables.get(doc.canonical_name[-1]) 2769 priv = ((var is not None and var.is_public is False) or 2770 (var is None and doc.canonical_name[-1].startswith('_'))) 2771 out(' <li%s> <strong class="uidlink">%s</strong>' 2772 % (priv and ' class="private"' or '', self.href(doc))) 2773 if doc.summary not in (None, UNKNOWN): 2774 out(': <em class="summary">'+ 2775 self.description(doc.summary, doc, 8)+'</em>') 2776 if doc.submodules != UNKNOWN and doc.submodules: 2777 if priv: out('\n <ul class="private">\n') 2778 else: out('\n <ul>\n') 2779 for submodule in doc.submodules: 2780 self.write_module_tree_item(out, submodule, package=doc) 2781 out(' </ul>\n') 2782 out(' </li>\n')
    2783 2784 #//////////////////////////////////////////////////////////// 2785 #{ Class trees 2786 #//////////////////////////////////////////////////////////// 2787 2788 write_class_tree_item = compile_template( 2789 ''' 2790 write_class_tree_item(self, out, doc, class_set) 2791 ''', 2792 # /------------------------- Template -------------------------\ 2793 ''' 2794 >>> if doc.summary in (None, UNKNOWN): 2795 <li> <strong class="uidlink">$self.href(doc)$</strong> 2796 >>> else: 2797 <li> <strong class="uidlink">$self.href(doc)$</strong>: 2798 <em class="summary">$self.description(doc.summary, doc, 8)$</em> 2799 >>> # endif 2800 >>> if doc.subclasses: 2801 <ul> 2802 >>> for subclass in sorted(set(doc.subclasses), key=lambda c:c.canonical_name[-1]): 2803 >>> if subclass in class_set: 2804 >>> self.write_class_tree_item(out, subclass, class_set) 2805 >>> #endif 2806 >>> #endfor 2807 </ul> 2808 >>> #endif 2809 </li> 2810 ''') 2811 # \------------------------------------------------------------/ 2812 2813 #//////////////////////////////////////////////////////////// 2814 #{ Standard Fields 2815 #//////////////////////////////////////////////////////////// 2816
    2817 - def write_standard_fields(self, out, doc):
    2818 """ 2819 Write HTML code containing descriptions of any standard markup 2820 fields that are defined by the given L{APIDoc} object (such as 2821 C{@author} and C{@todo} fields). 2822 2823 @param doc: The L{APIDoc} object containing the API documentation 2824 for the object whose standard markup fields should be 2825 described. 2826 """ 2827 fields = [] 2828 field_values = {} 2829 2830 for (field, arg, descr) in doc.metadata: 2831 if field not in field_values: 2832 fields.append(field) 2833 if field.takes_arg: 2834 subfields = field_values.setdefault(field,{}) 2835 subfields.setdefault(arg,[]).append(descr) 2836 else: 2837 field_values.setdefault(field,[]).append(descr) 2838 2839 if not fields: return 2840 2841 out('<div class="fields">') 2842 for field in fields: 2843 if field.takes_arg: 2844 for arg, descrs in field_values[field].items(): 2845 self.write_standard_field(out, doc, field, descrs, arg) 2846 2847 else: 2848 self.write_standard_field(out, doc, field, field_values[field]) 2849 2850 out('</div>')
    2851 2852 write_standard_field = compile_template( 2853 """ 2854 write_standard_field(self, out, doc, field, descrs, arg='') 2855 2856 """, 2857 # /------------------------- Template -------------------------\ 2858 ''' 2859 >>> if arg: arglabel = " (%s)" % arg 2860 >>> else: arglabel = "" 2861 >>> if len(descrs) == 1: 2862 <p><strong>$field.singular+arglabel$:</strong> 2863 $self.description(descrs[0], doc, 8)$ 2864 </p> 2865 >>> elif field.short: 2866 <dl><dt>$field.plural+arglabel$:</dt> 2867 <dd> 2868 >>> for descr in descrs[:-1]: 2869 $self.description(descr, doc, 10)$, 2870 >>> # end for 2871 $self.description(descrs[-1], doc, 10)$ 2872 </dd> 2873 </dl> 2874 >>> else: 2875 <strong>$field.plural+arglabel$:</strong> 2876 <ul class="nomargin-top"> 2877 >>> for descr in descrs: 2878 <li> 2879 $self.description(descr, doc, 8)$ 2880 </li> 2881 >>> # end for 2882 </ul> 2883 >>> # end else 2884 >>> # end for 2885 ''') 2886 # \------------------------------------------------------------/ 2887 2888 #//////////////////////////////////////////////////////////// 2889 #{ Index generation 2890 #//////////////////////////////////////////////////////////// 2891 2892 #: A list of metadata indices that should be generated. Each 2893 #: entry in this list is a tuple C{(tag, label, short_label)}, 2894 #: where C{tag} is the cannonical tag of a metadata field; 2895 #: C{label} is a label for the index page; and C{short_label} 2896 #: is a shorter label, used in the index selector. 2897 METADATA_INDICES = [('bug', 'Bug List', 'Bugs'), 2898 ('todo', 'To Do List', 'To Do'), 2899 ('change', 'Change Log', 'Changes'), 2900 ('deprecated', 'Deprecation List', 'Deprecations'), 2901 ('since', 'Introductions List', 'Introductions'), 2902 ] 2903
    2904 - def build_identifier_index(self):
    2905 items = [] 2906 for doc in self.indexed_docs: 2907 name = plaintext_to_html(doc.canonical_name[-1]) 2908 if isinstance(doc, RoutineDoc): name += '()' 2909 url = self.url(doc) 2910 if not url: continue 2911 container = self.docindex.container(doc) 2912 items.append( (name, url, container) ) 2913 return sorted(items, key=lambda v:v[0].lower())
    2914
    2915 - def _group_by_letter(self, items):
    2916 """Preserves sort order of the input.""" 2917 index = {} 2918 for item in items: 2919 first_letter = item[0][0].upper() 2920 if not ("A" <= first_letter <= "Z"): 2921 first_letter = '_' 2922 index.setdefault(first_letter, []).append(item) 2923 return index
    2924
    2925 - def build_term_index(self):
    2926 items = [] 2927 for doc in self.indexed_docs: 2928 url = self.url(doc) 2929 items += self._terms_from_docstring(url, doc, doc.descr) 2930 for (field, arg, descr) in doc.metadata: 2931 items += self._terms_from_docstring(url, doc, descr) 2932 if hasattr(doc, 'type_descr'): 2933 items += self._terms_from_docstring(url, doc, 2934 doc.type_descr) 2935 if hasattr(doc, 'return_descr'): 2936 items += self._terms_from_docstring(url, doc, 2937 doc.return_descr) 2938 if hasattr(doc, 'return_type'): 2939 items += self._terms_from_docstring(url, doc, 2940 doc.return_type) 2941 return sorted(items, key=lambda v:v[0].lower())
    2942
    2943 - def _terms_from_docstring(self, base_url, container, parsed_docstring):
    2944 if parsed_docstring in (None, UNKNOWN): return [] 2945 terms = [] 2946 # Strip any existing anchor off: 2947 base_url = re.sub('#.*', '', '%s' % (base_url,)) 2948 for term in parsed_docstring.index_terms(): 2949 anchor = self._term_index_to_anchor(term) 2950 url = '%s#%s' % (base_url, anchor) 2951 terms.append( (term.to_plaintext(None), url, container) ) 2952 return terms
    2953
    2954 - def build_metadata_index(self, field_name):
    2955 # Build the index. 2956 index = {} 2957 for doc in self.indexed_docs: 2958 if (not self._show_private and 2959 self._doc_or_ancestor_is_private(doc)): 2960 continue 2961 descrs = {} 2962 if doc.metadata is not UNKNOWN: 2963 for (field, arg, descr) in doc.metadata: 2964 if field.tags[0] == field_name: 2965 descrs.setdefault(arg, []).append(descr) 2966 for (arg, descr_list) in descrs.iteritems(): 2967 index.setdefault(arg, []).append( (doc, descr_list) ) 2968 return index
    2969
    2970 - def _term_index_to_anchor(self, term):
    2971 """ 2972 Given the name of an inline index item, construct a URI anchor. 2973 These anchors are used to create links from the index page to each 2974 index item. 2975 """ 2976 # Include "-" so we don't accidentally collide with the name 2977 # of a python identifier. 2978 s = re.sub(r'\s\s+', '-', term.to_plaintext(None)) 2979 return "index-"+re.sub("[^a-zA-Z0-9]", "_", s)
    2980 2981 #//////////////////////////////////////////////////////////// 2982 #{ Redirect page 2983 #//////////////////////////////////////////////////////////// 2984
    2985 - def write_redirect_page(self, out):
    2986 """ 2987 Build the auto-redirect page, which translates dotted names to 2988 URLs using javascript. When the user visits 2989 <redirect.html#dotted.name>, they will automatically get 2990 redirected to the page for the object with the given 2991 fully-qualified dotted name. E.g., for epydoc, 2992 <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to 2993 <epydoc.apidoc-module.html#UNKNOWN>. 2994 """ 2995 # Construct a list of all the module & class pages that we're 2996 # documenting. The redirect_url javascript will scan through 2997 # this list, looking for a page name that matches the 2998 # requested dotted name. 2999 pages = (['%s-m' % val_doc.canonical_name 3000 for val_doc in self.module_list] + 3001 ['%s-c' % val_doc.canonical_name 3002 for val_doc in self.class_list]) 3003 # Sort the pages from longest to shortest. This ensures that 3004 # we find e.g. "x.y.z" in the list before "x.y". 3005 pages = sorted(pages, key=lambda p:-len(p)) 3006 3007 # Write the redirect page. 3008 self._write_redirect_page(out, pages)
    3009 3010 _write_redirect_page = compile_template( 3011 ''' 3012 _write_redirect_page(self, out, pages) 3013 ''', 3014 # /------------------------- Template -------------------------\ 3015 ''' 3016 <html><head><title>Epydoc Redirect Page</title> 3017 <meta http-equiv="cache-control" content="no-cache" /> 3018 <meta http-equiv="expires" content="0" /> 3019 <meta http-equiv="pragma" content="no-cache" /> 3020 <script type="text/javascript" src="epydoc.js"></script> 3021 </head> 3022 <body> 3023 <script type="text/javascript"> 3024 <!-- 3025 var pages = $"[%s]" % ", ".join(['"%s"' % v for v in pages])$; 3026 var dottedName = get_anchor(); 3027 if (dottedName) { 3028 var target = redirect_url(dottedName); 3029 if (target) window.location.replace(target); 3030 } 3031 // --> 3032 </script> 3033 3034 <h3>Epydoc Auto-redirect page</h3> 3035 3036 <p>When javascript is enabled, this page will redirect URLs of 3037 the form <tt>redirect.html#<i>dotted.name</i></tt> to the 3038 documentation for the object with the given fully-qualified 3039 dotted name.</p> 3040 <p><a id="message"> &nbsp; </a></p> 3041 3042 <script type="text/javascript"> 3043 <!-- 3044 if (dottedName) { 3045 var msg = document.getElementById("message"); 3046 msg.innerHTML = "No documentation found for <tt>"+ 3047 dottedName+"</tt>"; 3048 } 3049 // --> 3050 </script> 3051 3052 </body> 3053 </html> 3054 ''') 3055 # \------------------------------------------------------------/ 3056 3057 #//////////////////////////////////////////////////////////// 3058 #{ URLs list 3059 #//////////////////////////////////////////////////////////// 3060
    3061 - def write_api_list(self, out):
    3062 """ 3063 Write a list of mapping name->url for all the documented objects. 3064 """ 3065 # Construct a list of all the module & class pages that we're 3066 # documenting. The redirect_url javascript will scan through 3067 # this list, looking for a page name that matches the 3068 # requested dotted name. 3069 skip = (ModuleDoc, ClassDoc, type(UNKNOWN)) 3070 for val_doc in self.module_list: 3071 self.write_url_record(out, val_doc) 3072 for var in val_doc.variables.itervalues(): 3073 if not isinstance(var.value, skip): 3074 self.write_url_record(out, var) 3075 3076 for val_doc in self.class_list: 3077 self.write_url_record(out, val_doc) 3078 for var in val_doc.variables.itervalues(): 3079 self.write_url_record(out, var)
    3080
    3081 - def write_url_record(self, out, obj):
    3082 url = self.url(obj) 3083 if url is not None: 3084 out("%s\t%s\n" % (obj.canonical_name, url))
    3085 3086 #//////////////////////////////////////////////////////////// 3087 #{ Helper functions 3088 #//////////////////////////////////////////////////////////// 3089
    3090 - def _val_is_public(self, valdoc):
    3091 """Make a best-guess as to whether the given class is public.""" 3092 container = self.docindex.container(valdoc) 3093 if isinstance(container, NamespaceDoc): 3094 for vardoc in container.variables.values(): 3095 if vardoc in (UNKNOWN, None): continue 3096 if vardoc.value is valdoc: 3097 return vardoc.is_public 3098 return True
    3099 3100 # [XX] Is it worth-while to pull the anchor tricks that I do here? 3101 # Or should I just live with the fact that show/hide private moves 3102 # stuff around? 3103 write_table_header = compile_template( 3104 ''' 3105 write_table_header(self, out, css_class, heading=None, \ 3106 private_link=True, colspan=2) 3107 ''', 3108 # /------------------------- Template -------------------------\ 3109 ''' 3110 >>> if heading is not None: 3111 >>> anchor = "section-%s" % re.sub("\W", "", heading) 3112 <!-- ==================== $heading.upper()$ ==================== --> 3113 <a name="$anchor$"></a> 3114 >>> #endif 3115 <table class="$css_class$" border="1" cellpadding="3" 3116 cellspacing="0" width="100%" bgcolor="white"> 3117 >>> if heading is not None: 3118 <tr bgcolor="#70b0f0" class="table-header"> 3119 >>> if private_link and self._show_private: 3120 <td colspan="$colspan$" class="table-header"> 3121 <table border="0" cellpadding="0" cellspacing="0" width="100%"> 3122 <tr valign="top"> 3123 <td align="left"><span class="table-header">$heading$</span></td> 3124 <td align="right" valign="top" 3125 ><span class="options">[<a href="#$anchor$" 3126 class="privatelink" onclick="toggle_private();" 3127 >hide private</a>]</span></td> 3128 </tr> 3129 </table> 3130 </td> 3131 >>> else: 3132 <td align="left" colspan="2" class="table-header"> 3133 <span class="table-header">$heading$</span></td> 3134 >>> #endif 3135 </tr> 3136 >>> #endif 3137 ''') 3138 # \------------------------------------------------------------/ 3139 3140 TABLE_FOOTER = '</table>\n' 3141 3142 PRIVATE_LINK = ''' 3143 <span class="options">[<a href="javascript:void(0);" class="privatelink" 3144 onclick="toggle_private();">hide&nbsp;private</a>]</span> 3145 '''.strip() 3146 3147 write_group_header = compile_template( 3148 ''' 3149 write_group_header(self, out, group, tr_class='') 3150 ''', 3151 # /------------------------- Template -------------------------\ 3152 ''' 3153 <tr bgcolor="#e8f0f8" $tr_class$> 3154 <th colspan="2" class="group-header" 3155 >&nbsp;&nbsp;&nbsp;&nbsp;$group$</th></tr> 3156 ''') 3157 # \------------------------------------------------------------/ 3158 3159 _url_cache = {}
    3160 - def url(self, obj):
    3161 """ 3162 Return the URL for the given object, which can be a 3163 C{VariableDoc}, a C{ValueDoc}, or a C{DottedName}. 3164 """ 3165 cached_url = self._url_cache.get(id(obj)) 3166 if cached_url is not None: 3167 return cached_url 3168 else: 3169 url = self._url_cache[id(obj)] = self._url(obj) 3170 return url
    3171
    3172 - def _url(self, obj):
    3173 """ 3174 Internal helper for L{url}. 3175 """ 3176 # Module: <canonical_name>-module.html 3177 if isinstance(obj, ModuleDoc): 3178 if obj not in self.module_set: return None 3179 return urllib.quote('%s'%obj.canonical_name) + '-module.html' 3180 # Class: <canonical_name>-class.html 3181 elif isinstance(obj, ClassDoc): 3182 if obj not in self.class_set: return None 3183 return urllib.quote('%s'%obj.canonical_name) + '-class.html' 3184 # Variable 3185 elif isinstance(obj, VariableDoc): 3186 val_doc = obj.value 3187 if isinstance(val_doc, (ModuleDoc, ClassDoc)): 3188 return self.url(val_doc) 3189 elif obj.container in (None, UNKNOWN): 3190 if val_doc in (None, UNKNOWN): return None 3191 return self.url(val_doc) 3192 elif obj.is_imported == True: 3193 if obj.imported_from is not UNKNOWN: 3194 return self.url(obj.imported_from) 3195 else: 3196 return None 3197 else: 3198 container_url = self.url(obj.container) 3199 if container_url is None: return None 3200 return '%s#%s' % (container_url, urllib.quote('%s'%obj.name)) 3201 # Value (other than module or class) 3202 elif isinstance(obj, ValueDoc): 3203 container = self.docindex.container(obj) 3204 if container is None: 3205 return None # We couldn't find it! 3206 else: 3207 container_url = self.url(container) 3208 if container_url is None: return None 3209 anchor = urllib.quote('%s'%obj.canonical_name[-1]) 3210 return '%s#%s' % (container_url, anchor) 3211 # Dotted name: look up the corresponding APIDoc 3212 elif isinstance(obj, DottedName): 3213 val_doc = self.docindex.get_valdoc(obj) 3214 if val_doc is None: return None 3215 return self.url(val_doc) 3216 # Special pages: 3217 elif obj == 'indices': 3218 return 'identifier-index.html' 3219 elif obj == 'help': 3220 return 'help.html' 3221 elif obj == 'trees': 3222 return self._trees_url 3223 else: 3224 raise ValueError, "Don't know what to do with %r" % obj
    3225 3235
    3236 - def pysrc_url(self, api_doc):
    3237 if isinstance(api_doc, VariableDoc): 3238 if api_doc.value not in (None, UNKNOWN): 3239 return pysrc_url(api_doc.value) 3240 else: 3241 return None 3242 elif isinstance(api_doc, ModuleDoc): 3243 if api_doc in self.modules_with_sourcecode: 3244 return ('%s-pysrc.html' % 3245 urllib.quote('%s' % api_doc.canonical_name)) 3246 else: 3247 return None 3248 else: 3249 module = api_doc.defining_module 3250 if module == UNKNOWN: return None 3251 module_pysrc_url = self.pysrc_url(module) 3252 if module_pysrc_url is None: return None 3253 module_name = module.canonical_name 3254 if not module_name.dominates(api_doc.canonical_name, True): 3255 log.debug('%r is in %r but name does not dominate' % 3256 (api_doc, module)) 3257 return module_pysrc_url 3258 mname_len = len(module.canonical_name) 3259 anchor = '%s' % api_doc.canonical_name[mname_len:] 3260 return '%s#%s' % (module_pysrc_url, urllib.quote(anchor)) 3261 3262 # We didn't find it: 3263 return None
    3264 3265 # [xx] add code to automatically do <code> wrapping or the like?
    3266 - def href(self, target, label=None, css_class=None, context=None, 3267 tooltip=None):
    3268 """ 3269 Return the HTML code for an HREF link to the given target 3270 (which can be a C{VariableDoc}, a C{ValueDoc}, or a 3271 C{DottedName}. 3272 If a C{NamespaceDoc} C{context} is specified, the target label is 3273 contextualized to it. 3274 """ 3275 assert isinstance(target, (APIDoc, DottedName)) 3276 3277 # Pick a label, if none was given. 3278 if label is None: 3279 if isinstance(target, VariableDoc): 3280 label = target.name 3281 elif (isinstance(target, ValueDoc) and 3282 target.canonical_name is not UNKNOWN): 3283 label = target.canonical_name 3284 elif isinstance(target, DottedName): 3285 label = target 3286 elif isinstance(target, GenericValueDoc): 3287 raise ValueError("href() should not be called with " 3288 "GenericValueDoc objects (perhaps you " 3289 "meant to use the containing variable?)") 3290 else: 3291 raise ValueError("Unable to find a label for %r" % target) 3292 3293 if context is not None and isinstance(label, DottedName): 3294 label = label.contextualize(context.canonical_name.container()) 3295 3296 label = plaintext_to_html(str(label)) 3297 3298 # Munge names for scripts & unreachable values 3299 if label.startswith('script-'): 3300 label = label[7:] + ' (script)' 3301 if label.startswith('??'): 3302 label = '<i>unreachable</i>' + label[2:] 3303 label = re.sub(r'-\d+$', '', label) 3304 3305 # Get the url for the target. 3306 url = self.url(target) 3307 if url is None: 3308 if tooltip: return '<span title="%s">%s</span>' % (tooltip, label) 3309 else: return label 3310 3311 # Construct a string for the class attribute. 3312 if css_class is None: 3313 css = '' 3314 else: 3315 css = ' class="%s"' % css_class 3316 3317 onclick = '' 3318 if ((isinstance(target, VariableDoc) and not target.is_public) or 3319 (isinstance(target, ValueDoc) and 3320 not isinstance(target, GenericValueDoc) and 3321 not self._val_is_public(target))): 3322 onclick = ' onclick="show_private();"' 3323 3324 if tooltip: 3325 tooltip = ' title="%s"' % tooltip 3326 else: 3327 tooltip = '' 3328 3329 return '<a href="%s"%s%s%s>%s</a>' % (url, css, onclick, tooltip, label)
    3330
    3331 - def _attr_to_html(self, attr, api_doc, indent):
    3332 if api_doc in (None, UNKNOWN): 3333 return '' 3334 pds = getattr(api_doc, attr, None) # pds = ParsedDocstring. 3335 if pds not in (None, UNKNOWN): 3336 return self.docstring_to_html(pds, api_doc, indent) 3337 elif isinstance(api_doc, VariableDoc): 3338 return self._attr_to_html(attr, api_doc.value, indent)
    3339
    3340 - def summary(self, api_doc, indent=0):
    3341 return self._attr_to_html('summary', api_doc, indent)
    3342
    3343 - def descr(self, api_doc, indent=0):
    3344 return self._attr_to_html('descr', api_doc, indent)
    3345
    3346 - def type_descr(self, api_doc, indent=0):
    3347 return self._attr_to_html('type_descr', api_doc, indent)
    3348
    3349 - def return_type(self, api_doc, indent=0):
    3350 return self._attr_to_html('return_type', api_doc, indent)
    3351
    3352 - def return_descr(self, api_doc, indent=0):
    3353 return self._attr_to_html('return_descr', api_doc, indent)
    3354
    3355 - def docstring_to_html(self, parsed_docstring, where=None, indent=0):
    3356 if parsed_docstring in (None, UNKNOWN): return '' 3357 linker = _HTMLDocstringLinker(self, where) 3358 s = parsed_docstring.to_html(linker, indent=indent, 3359 directory=self._directory, 3360 docindex=self.docindex, 3361 context=where).strip() 3362 if self._mark_docstrings: 3363 s = '<span class="docstring">%s</span><!--end docstring-->' % s 3364 return s
    3365
    3366 - def description(self, parsed_docstring, where=None, indent=0):
    3367 assert isinstance(where, (APIDoc, type(None))) 3368 if parsed_docstring in (None, UNKNOWN): return '' 3369 linker = _HTMLDocstringLinker(self, where) 3370 descr = parsed_docstring.to_html(linker, indent=indent, 3371 directory=self._directory, 3372 docindex=self.docindex, 3373 context=where).strip() 3374 if descr == '': return '&nbsp;' 3375 return descr
    3376 3377 # [xx] Should this be defined by the APIDoc classes themselves??
    3378 - def doc_kind(self, doc):
    3379 if isinstance(doc, ModuleDoc) and doc.is_package == True: 3380 return 'Package' 3381 elif (isinstance(doc, ModuleDoc) and 3382 doc.canonical_name[0].startswith('script')): 3383 return 'Script' 3384 elif isinstance(doc, ModuleDoc): 3385 return 'Module' 3386 elif isinstance(doc, ClassDoc): 3387 return 'Class' 3388 elif isinstance(doc, ClassMethodDoc): 3389 return 'Class Method' 3390 elif isinstance(doc, StaticMethodDoc): 3391 return 'Static Method' 3392 elif isinstance(doc, RoutineDoc): 3393 if isinstance(self.docindex.container(doc), ClassDoc): 3394 return 'Method' 3395 else: 3396 return 'Function' 3397 else: 3398 return 'Variable'
    3399
    3400 - def _doc_or_ancestor_is_private(self, api_doc):
    3401 name = api_doc.canonical_name 3402 for i in range(len(name), 0, -1): 3403 # Is it (or an ancestor) a private var? 3404 var_doc = self.docindex.get_vardoc(name[:i]) 3405 if var_doc is not None and var_doc.is_public == False: 3406 return True 3407 # Is it (or an ancestor) a private module? 3408 val_doc = self.docindex.get_valdoc(name[:i]) 3409 if (val_doc is not None and isinstance(val_doc, ModuleDoc) and 3410 val_doc.canonical_name[-1].startswith('_')): 3411 return True 3412 return False
    3413
    3414 - def _private_subclasses(self, class_doc):
    3415 """Return a list of all subclasses of the given class that are 3416 private, as determined by L{_val_is_private}. Recursive 3417 subclasses are included in this list.""" 3418 queue = [class_doc] 3419 private = set() 3420 for cls in queue: 3421 if (isinstance(cls, ClassDoc) and 3422 cls.subclasses not in (None, UNKNOWN)): 3423 queue.extend(cls.subclasses) 3424 private.update([c for c in cls.subclasses if 3425 not self._val_is_public(c)]) 3426 return private
    3427
    3428 -class _HTMLDocstringLinker(epydoc.markup.DocstringLinker):
    3429 - def __init__(self, htmlwriter, container):
    3430 self.htmlwriter = htmlwriter 3431 self.docindex = htmlwriter.docindex 3432 self.container = container
    3433
    3434 - def translate_indexterm(self, indexterm):
    3435 key = self.htmlwriter._term_index_to_anchor(indexterm) 3436 return ('<a name="%s"></a><i class="indexterm">%s</i>' % 3437 (key, indexterm.to_html(self)))
    3438
    3439 - def translate_identifier_xref(self, identifier, label=None):
    3440 # Pick a label for this xref. 3441 if label is None: label = plaintext_to_html(identifier) 3442 3443 # Find the APIDoc for it (if it's available). 3444 doc = self.docindex.find(identifier, self.container) 3445 3446 # If we didn't find a target, then try checking in the contexts 3447 # of the ancestor classes. 3448 if doc is None and isinstance(self.container, RoutineDoc): 3449 container = self.docindex.get_vardoc( 3450 self.container.canonical_name) 3451 while (doc is None and container not in (None, UNKNOWN) 3452 and container.overrides not in (None, UNKNOWN)): 3453 container = container.overrides 3454 doc = self.docindex.find(identifier, container) 3455 3456 # Translate it into HTML. 3457 if doc is None: 3458 self._failed_xref(identifier) 3459 return '<code class="link">%s</code>' % label 3460 else: 3461 return self.htmlwriter.href(doc, label, 'link')
    3462 3463 # [xx] Should this be added to the DocstringLinker interface??? 3464 # Currently, this is *only* used by dotgraph.
    3465 - def url_for(self, identifier):
    3466 if isinstance(identifier, (basestring, DottedName)): 3467 doc = self.docindex.find(identifier, self.container) 3468 if doc: 3469 return self.htmlwriter.url(doc) 3470 else: 3471 return None 3472 3473 elif isinstance(identifier, APIDoc): 3474 return self.htmlwriter.url(identifier) 3475 doc = identifier 3476 3477 else: 3478 raise TypeError('Expected string or APIDoc')
    3479
    3480 - def _failed_xref(self, identifier):
    3481 """Add an identifier to the htmlwriter's failed crossreference 3482 list.""" 3483 # Don't count it as a failed xref if it's a parameter of the 3484 # current function. 3485 if (isinstance(self.container, RoutineDoc) and 3486 identifier in self.container.all_args()): 3487 return 3488 3489 failed_xrefs = self.htmlwriter._failed_xrefs 3490 context = self.container.canonical_name 3491 failed_xrefs.setdefault(identifier,{})[context] = 1
    3492

    epydoc-3.0.1+dfsg/doc/api/epydoc.log-module.html0000644000175000017500000011066710750103050021731 0ustar pronovicpronovic epydoc.log
    Package epydoc :: Module log
    [hide private]
    [frames] | no frames]

    Module log

    source code

    Functions used to report messages and progress updates to the user. These functions are delegated to zero or more registered Logger objects, which are responsible for actually presenting the information to the user. Different interfaces are free to create and register their own Loggers, allowing them to present this information in the manner that is best suited to each interface.


    Note: I considered using the standard logging package to provide this functionality. However, I found that it would be too difficult to get that package to provide the behavior I want (esp. with respect to progress displays; but also with respect to message blocks).

    Classes [hide private]
      Logger
    An abstract base class that defines the interface for loggers, which are used by epydoc to report information back to the user.
      SimpleLogger
    Functions [hide private]
     
    register_logger(logger)
    Register a logger.
    source code
     
    remove_logger(logger) source code
     
    fatal(*messages)
    Display the given fatal message.
    source code
     
    error(*messages)
    Display the given error message.
    source code
     
    warning(*messages)
    Display the given warning message.
    source code
    call graph 
     
    docstring_warning(*messages)
    Display the given docstring warning message.
    source code
    call graph 
     
    info(*messages)
    Display the given informational message.
    source code
    call graph 
     
    debug(*messages)
    Display the given debugging message.
    source code
     
    start_block(header)
    Start a new message block.
    source code
     
    end_block()
    End a warning block.
    source code
     
    start_progress(header=None)
    Begin displaying progress for a new task.
    source code
    call graph 
     
    end_progress()
    Finish off the display of progress for the current task.
    source code
    call graph 
     
    progress(percent, message='')
    Update the progress display.
    source code
    call graph 
     
    close() source code
    Variables [hide private]
      DOCSTRING_WARNING = 25
      _loggers = []
    The list of registered logging functions.
        Message Severity Levels
      DEBUG = 10
      INFO = 20
      WARNING = 30
      ERROR = 40
      FATAL = 40
    Function Details [hide private]

    register_logger(logger)

    source code 

    Register a logger. Each call to one of the logging functions defined by this module will be delegated to each registered logger.

    start_block(header)

    source code 

    Start a new message block. Any calls to info(), warning(), or error() that occur between a call to start_block and a corresponding call to end_block will be grouped together, and displayed with a common header. start_block can be called multiple times (to form nested blocks), but every call to start_block must be balanced by a call to end_block.

    end_block()

    source code 

    End a warning block. See start_block for details.

    start_progress(header=None)

    source code 
    call graph 

    Begin displaying progress for a new task. header is a description of the task for which progress is being reported. Each call to start_progress must be followed by a call to end_progress (with no intervening calls to start_progress).

    end_progress()

    source code 
    call graph 

    Finish off the display of progress for the current task. See start_progress for more information.

    progress(percent, message='')

    source code 
    call graph 

    Update the progress display.

    Parameters:
    • percent - A float from 0.0 to 1.0, indicating how much progress has been made.
    • message - A message indicating the most recent action that contributed towards that progress.

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink.DocUrlGenerator-class.html0000644000175000017500000005646410750103050027160 0ustar pronovicpronovic epydoc.docwriter.xlink.DocUrlGenerator
    Package epydoc :: Package docwriter :: Module xlink :: Class DocUrlGenerator
    [hide private]
    [frames] | no frames]

    Class DocUrlGenerator

    source code


    Read a documentation index and generate URL's for it.
    Nested Classes [hide private]

    Inherited from UrlGenerator: IndexAmbiguous

    Instance Methods [hide private]
     
    __init__(self) source code
    str
    get_url(self, name)
    Look for a name and return the matching URL documentation.
    source code

    Inherited from UrlGenerator: get_canonical_name

        Content loading
     
    clear(self)
    Clear the current class content.
    source code
     
    load_index(self, f)
    Read the content of an index file.
    source code
     
    _iter_tuples(self, f)
    Iterate on a file returning 2-tuples.
    source code
     
    load_records(self, records)
    Read a sequence of pairs name -> url and populate the internal maps.
    source code
    Class Variables [hide private]

    Inherited from UrlGenerator (private): _SEP_RE

    Instance Variables [hide private]
      _exact_matches
    A map from an object fully qualified name to its URL.
      _partial_names
    A map from partial names to the fully qualified names they may refer.
      prefix
    Prefix portion for the URL's returned by get_url().
      _filename
    Not very important: only for logging.
    Method Details [hide private]

    get_url(self, name)

    source code 

    Look for a name and return the matching URL documentation.

    First look for a fully qualified name. If not found, try with partial name.

    If no url exists for the given object, return None.

    Parameters:
    • name - the name to look for
    Returns: str
    the URL that can be used to reach the name documentation. None if no such URL exists.
    Raises:
    • IndexError - no object found with name
    • DocUrlGenerator.IndexAmbiguous - more than one object found with a non-fully qualified name; notice that this is an IndexError subclass
    Overrides: UrlGenerator.get_url
    (inherited documentation)

    load_index(self, f)

    source code 

    Read the content of an index file.

    Populate the internal maps with the file content using load_records().

    Parameters:
    • f (str or file) - a file name or file-like object fron which read the index.

    load_records(self, records)

    source code 
    Read a sequence of pairs name -> url and populate the internal maps.
    Parameters:
    • records (iterable) - the sequence of pairs (name, url) to add to the maps.

    Instance Variable Details [hide private]

    _exact_matches

    A map from an object fully qualified name to its URL.

    Values are both the name as tuple of fragments and as read from the records (see load_records()), mostly to help _partial_names to perform lookup for unambiguous names.

    _partial_names

    A map from partial names to the fully qualified names they may refer.

    The keys are the possible left sub-tuples of fully qualified names, the values are list of strings as provided by the index.

    If the list for a given tuple contains a single item, the partial match is not ambuguous. In this case the string can be looked up in _exact_matches.

    If the name fragment is ambiguous, a warning may be issued to the user. The items can be used to provide an informative message to the user, to help him qualifying the name in a unambiguous manner.


    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.ParsedEpytextDocstring-class.html0000644000175000017500000017750310750103050030447 0ustar pronovicpronovic epydoc.markup.epytext.ParsedEpytextDocstring
    Package epydoc :: Package markup :: Module epytext :: Class ParsedEpytextDocstring
    [hide private]
    [frames] | no frames]

    Class ParsedEpytextDocstring

    source code


    Instance Methods [hide private]
     
    __init__(self, dom_tree, **options) source code
    call graph 
     
    __str__(self) source code
    string
    to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options)
    Translate this docstring to HTML.
    source code
    call graph 
    string
    to_latex(self, docstring_linker, **options)
    Translate this docstring to LaTeX.
    source code
    string
    to_plaintext(self, docstring_linker, **options)
    Translate this docstring to plaintext.
    source code
    call graph 
     
    _index_term_key(self, tree) source code
     
    _to_html(self, tree, linker, directory, docindex, context, indent=0, seclevel=0) source code
    call graph 
     
    _build_graph(self, graph_type, graph_args, linker, docindex, context) source code
    call graph 
     
    _to_latex(self, tree, linker, indent=0, seclevel=0, breakany=0) source code
    (ParsedDocstring, bool)
    summary(self)
    Returns: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary.
    source code
    call graph 
    (ParsedDocstring, list of Field)
    split_fields(self, errors=None)
    Split this docstring into its body and its fields.
    source code
    call graph 
    list of ParsedDocstring
    index_terms(self)
    Returns: The list of index terms that are defined in this docstring.
    source code
    call graph 
     
    _index_terms(self, tree, terms) source code
    call graph 

    Inherited from ParsedDocstring: __add__, concatenate

    Class Variables [hide private]
      SYMBOL_TO_HTML = {'->': '&rarr;', '<-': '&larr;', '<=': '&le;'...
      SYMBOL_TO_LATEX = {'->': '\\(\\rightarrow\\)', '<-': '\\(\\lef...
      _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)')
    Method Details [hide private]

    to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options)

    source code 
    call graph 

    Translate this docstring to HTML.

    Parameters:
    • docstring_linker - An HTML translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    An HTML fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_html
    (inherited documentation)

    to_latex(self, docstring_linker, **options)

    source code 

    Translate this docstring to LaTeX.

    Parameters:
    • docstring_linker - A LaTeX translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A LaTeX fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_latex
    (inherited documentation)

    to_plaintext(self, docstring_linker, **options)

    source code 
    call graph 

    Translate this docstring to plaintext.

    Parameters:
    • docstring_linker - A plaintext translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A plaintext fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_plaintext
    (inherited documentation)

    summary(self)

    source code 
    call graph 
    Returns: (ParsedDocstring, bool)
    A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring.
    Overrides: ParsedDocstring.summary
    (inherited documentation)

    split_fields(self, errors=None)

    source code 
    call graph 

    Split this docstring into its body and its fields.

    Parameters:
    • errors - A list where any errors generated during splitting will be stored. If no list is specified, then errors will be ignored.
    Returns: (ParsedDocstring, list of Field)
    A tuple (body, fields), where body is the main body of this docstring, and fields is a list of its fields. If the resulting body is empty, return None for the body.
    Overrides: ParsedDocstring.split_fields
    (inherited documentation)

    index_terms(self)

    source code 
    call graph 
    Returns: list of ParsedDocstring
    The list of index terms that are defined in this docstring. Each of these items will be added to the index page of the documentation.
    Overrides: ParsedDocstring.index_terms
    (inherited documentation)

    Class Variable Details [hide private]

    SYMBOL_TO_HTML

    Value:
    {'->': '&rarr;',
     '<-': '&larr;',
     '<=': '&le;',
     '>=': '&ge;',
     'Alpha': '&Alpha;',
     'Beta': '&Beta;',
     'Chi': '&Chi;',
     'Delta': '&Delta;',
    ...
    

    SYMBOL_TO_LATEX

    Value:
    {'->': '\\(\\rightarrow\\)',
     '<-': '\\(\\leftarrow\\)',
     '<=': '\\(\\le\\)',
     '>=': '\\(\\ge\\)',
     'Alpha': '\\(\\alpha\\)',
     'Beta': '\\(\\beta\\)',
     'Chi': '\\(\\chi\\)',
     'Delta': '\\(\\Delta\\)',
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.plaintext-module.html0000644000175000017500000002671710750103050024460 0ustar pronovicpronovic epydoc.markup.plaintext
    Package epydoc :: Package markup :: Module plaintext
    [hide private]
    [frames] | no frames]

    Module plaintext

    source code

    Parser for plaintext docstrings. Plaintext docstrings are rendered as verbatim output, preserving all whitespace.

    Classes [hide private]
      ParsedPlaintextDocstring
    Functions [hide private]
    ParsedPlaintextDocstring, list of ParseError
    parse_docstring(docstring, errors, **options)
    Returns: A pair (d, e), where d is a ParsedDocstring that encodes the contents of the given plaintext docstring; and e is a list of errors that were generated while parsing the docstring.
    source code
    call graph 
    Function Details [hide private]

    parse_docstring(docstring, errors, **options)

    source code 
    call graph 
    Returns: ParsedPlaintextDocstring, list of ParseError
    A pair (d, e), where d is a ParsedDocstring that encodes the contents of the given plaintext docstring; and e is a list of errors that were generated while parsing the docstring.

    epydoc-3.0.1+dfsg/doc/api/epydoc.cli.ConsoleLogger-class.html0000644000175000017500000006521610750103050024277 0ustar pronovicpronovic epydoc.cli.ConsoleLogger
    Package epydoc :: Module cli :: Class ConsoleLogger
    [hide private]
    [frames] | no frames]

    Class ConsoleLogger

    source code


    Instance Methods [hide private]
     
    __init__(self, verbosity, progress_mode=None) source code
     
    start_block(self, header)
    Start a new message block.
    source code
     
    end_block(self)
    End a warning block.
    source code
     
    _format(self, prefix, message, color)
    Rewrap the message; but preserve newlines, and don't touch any lines that begin with spaces.
    source code
     
    log(self, level, message)
    Display a message.
    source code
     
    _report(self, message) source code
     
    progress(self, percent, message='')
    Update the progress display.
    source code
     
    _timestr(self, dt) source code
     
    start_progress(self, header=None)
    Begin displaying progress for a new task.
    source code
     
    end_progress(self)
    Finish off the display of progress for the current task.
    source code
     
    print_times(self) source code

    Inherited from log.Logger: close

    Instance Variables [hide private]
      reported_message_levels
    This set contains all the message levels (WARNING, ERROR, etc) that have been reported.
      suppressed_docstring_warning
    This variable will be incremented once every time a docstring warning is reported tothe logger, but the verbosity level is too low for it to be displayed.
    Method Details [hide private]

    start_block(self, header)

    source code 

    Start a new message block. Any calls to info(), warning(), or error() that occur between a call to start_block and a corresponding call to end_block will be grouped together, and displayed with a common header. start_block can be called multiple times (to form nested blocks), but every call to start_block must be balanced by a call to end_block.

    Overrides: log.Logger.start_block
    (inherited documentation)

    end_block(self)

    source code 

    End a warning block. See start_block for details.

    Overrides: log.Logger.end_block
    (inherited documentation)

    log(self, level, message)

    source code 

    Display a message.

    Parameters:
    • message - The message string to display. message may contain newlines, but does not need to end in a newline.
    • level - An integer value indicating the severity of the message.
    Overrides: log.Logger.log
    (inherited documentation)

    progress(self, percent, message='')

    source code 

    Update the progress display.

    Parameters:
    • percent - A float from 0.0 to 1.0, indicating how much progress has been made.
    • message - A message indicating the most recent action that contributed towards that progress.
    Overrides: log.Logger.progress
    (inherited documentation)

    start_progress(self, header=None)

    source code 

    Begin displaying progress for a new task. header is a description of the task for which progress is being reported. Each call to start_progress must be followed by a call to end_progress (with no intervening calls to start_progress).

    Overrides: log.Logger.start_progress
    (inherited documentation)

    end_progress(self)

    source code 

    Finish off the display of progress for the current task. See start_progress for more information.

    Overrides: log.Logger.end_progress
    (inherited documentation)

    Instance Variable Details [hide private]

    reported_message_levels

    This set contains all the message levels (WARNING, ERROR, etc) that have been reported. It is used by the options --fail-on-warning etc to determine the return value.


    epydoc-3.0.1+dfsg/doc/api/toc-everything.html0000644000175000017500000021711310750103050021344 0ustar pronovicpronovic Everything

    Everything


    All Classes

    epydoc.apidoc.APIDoc
    epydoc.apidoc.ClassDoc
    epydoc.apidoc.ClassMethodDoc
    epydoc.apidoc.DocIndex
    epydoc.apidoc.DottedName
    epydoc.apidoc.DottedName.InvalidDottedName
    epydoc.apidoc.GenericValueDoc
    epydoc.apidoc.ModuleDoc
    epydoc.apidoc.NamespaceDoc
    epydoc.apidoc.PropertyDoc
    epydoc.apidoc.RoutineDoc
    epydoc.apidoc.StaticMethodDoc
    epydoc.apidoc.ValueDoc
    epydoc.apidoc.VariableDoc
    epydoc.checker.DocChecker
    epydoc.cli.ConsoleLogger
    epydoc.cli.HTMLLogger
    epydoc.cli.TerminalController
    epydoc.cli.UnifiedProgressConsoleLogger
    epydoc.docbuilder.BuildOptions
    epydoc.docparser.ParseError
    epydoc.docstringparser.DocstringField
    epydoc.docwriter.dotgraph.DotGraph
    epydoc.docwriter.dotgraph.DotGraphEdge
    epydoc.docwriter.dotgraph.DotGraphNode
    epydoc.docwriter.dotgraph.DotGraphUmlClassNode
    epydoc.docwriter.dotgraph.DotGraphUmlModuleNode
    epydoc.docwriter.html.HTMLWriter
    epydoc.docwriter.html_colorize.PythonSourceColorizer
    epydoc.docwriter.latex.LatexWriter
    epydoc.docwriter.plaintext.PlaintextWriter
    epydoc.docwriter.xlink.ApiLinkReader
    epydoc.docwriter.xlink.DocUrlGenerator
    epydoc.docwriter.xlink.UrlGenerator
    epydoc.docwriter.xlink.UrlGenerator.IndexAmbiguous
    epydoc.docwriter.xlink.VoidUrlGenerator
    epydoc.gui.EpydocGUI
    epydoc.gui.GUILogger
    epydoc.log.Logger
    epydoc.log.SimpleLogger
    epydoc.markup.ConcatenatedDocstring
    epydoc.markup.DocstringLinker
    epydoc.markup.Field
    epydoc.markup.ParseError
    epydoc.markup.ParsedDocstring
    epydoc.markup.doctest.DoctestColorizer
    epydoc.markup.doctest.HTMLDoctestColorizer
    epydoc.markup.doctest.LaTeXDoctestColorizer
    epydoc.markup.doctest.XMLDoctestColorizer
    epydoc.markup.epytext.ColorizingError
    epydoc.markup.epytext.Element
    epydoc.markup.epytext.ParsedEpytextDocstring
    epydoc.markup.epytext.StructuringError
    epydoc.markup.epytext.Token
    epydoc.markup.epytext.TokenizationError
    epydoc.markup.javadoc.ParsedJavadocDocstring
    epydoc.markup.plaintext.ParsedPlaintextDocstring
    epydoc.markup.pyval_repr.ColorizedPyvalRepr
    epydoc.markup.pyval_repr.PyvalColorizer
    epydoc.markup.restructuredtext.OptimizedReporter
    epydoc.markup.restructuredtext.ParsedRstDocstring
    epydoc.markup.restructuredtext.dotgraph
    epydoc.util.RunSubprocessError

    All Functions

    epydoc.apidoc.pp_apidoc
    epydoc.apidoc.reachable_valdocs
    epydoc.cli.check_docs
    epydoc.cli.cli
    epydoc.cli.main
    epydoc.cli.parse_arguments
    epydoc.cli.parse_configfiles
    epydoc.cli.pickle_persistent_id
    epydoc.cli.pickle_persistent_load
    epydoc.cli.write_html
    epydoc.cli.write_latex
    epydoc.cli.write_pickle
    epydoc.cli.write_text
    epydoc.compat.reversed
    epydoc.compat.sorted
    epydoc.docbuilder.assign_canonical_names
    epydoc.docbuilder.build_doc
    epydoc.docbuilder.build_doc_index
    epydoc.docbuilder.find_overrides
    epydoc.docbuilder.inherit_docs
    epydoc.docbuilder.link_imports
    epydoc.docbuilder.merge_attribute
    epydoc.docbuilder.merge_bases
    epydoc.docbuilder.merge_docs
    epydoc.docbuilder.merge_docs_extracted_by
    epydoc.docbuilder.merge_docstring
    epydoc.docbuilder.merge_fdel
    epydoc.docbuilder.merge_fget
    epydoc.docbuilder.merge_fset
    epydoc.docbuilder.merge_overrides
    epydoc.docbuilder.merge_posarg_defaults
    epydoc.docbuilder.merge_proxy_for
    epydoc.docbuilder.merge_submodules
    epydoc.docbuilder.merge_value
    epydoc.docbuilder.merge_variables
    epydoc.docbuilder.register_attribute_mergefunc
    epydoc.docintrospecter.clear_cache
    epydoc.docintrospecter.get_canonical_name
    epydoc.docintrospecter.get_containing_module
    epydoc.docintrospecter.get_docstring
    epydoc.docintrospecter.get_value_from_filename
    epydoc.docintrospecter.get_value_from_name
    epydoc.docintrospecter.get_value_from_scriptname
    epydoc.docintrospecter.introspect_class
    epydoc.docintrospecter.introspect_docs
    epydoc.docintrospecter.introspect_docstring_lineno
    epydoc.docintrospecter.introspect_module
    epydoc.docintrospecter.introspect_other
    epydoc.docintrospecter.introspect_property
    epydoc.docintrospecter.introspect_routine
    epydoc.docintrospecter.is_classmethod
    epydoc.docintrospecter.is_future_feature
    epydoc.docintrospecter.is_getset
    epydoc.docintrospecter.is_member
    epydoc.docintrospecter.is_property
    epydoc.docintrospecter.is_staticmethod
    epydoc.docintrospecter.isclass
    epydoc.docintrospecter.register_class_type
    epydoc.docintrospecter.register_introspecter
    epydoc.docintrospecter.value_repr
    epydoc.docintrospecter.verify_name
    epydoc.docparser.add_docstring_from_comments
    epydoc.docparser.add_to_group
    epydoc.docparser.apply_decorator
    epydoc.docparser.del_variable
    epydoc.docparser.dotted_names_in
    epydoc.docparser.find_base
    epydoc.docparser.flatten
    epydoc.docparser.get_lhs_parent
    epydoc.docparser.get_module_encoding
    epydoc.docparser.handle_special_module_vars
    epydoc.docparser.init_arglist
    epydoc.docparser.lhs_is_instvar
    epydoc.docparser.lookup_name
    epydoc.docparser.lookup_value
    epydoc.docparser.lookup_variable
    epydoc.docparser.parse_classdef_bases
    epydoc.docparser.parse_docs
    epydoc.docparser.parse_dotted_name
    epydoc.docparser.parse_dotted_name_list
    epydoc.docparser.parse_funcdef_arg
    epydoc.docparser.parse_name
    epydoc.docparser.parse_string
    epydoc.docparser.parse_string_list
    epydoc.docparser.pp_toktree
    epydoc.docparser.process_assignment
    epydoc.docparser.process_classdef
    epydoc.docparser.process_control_flow_line
    epydoc.docparser.process_del
    epydoc.docparser.process_docstring
    epydoc.docparser.process_file
    epydoc.docparser.process_from_import
    epydoc.docparser.process_funcdef
    epydoc.docparser.process_import
    epydoc.docparser.process_line
    epydoc.docparser.process_multi_stmt
    epydoc.docparser.process_one_line_block
    epydoc.docparser.rhs_to_valuedoc
    epydoc.docparser.script_guard
    epydoc.docparser.set_variable
    epydoc.docparser.shallow_parse
    epydoc.docparser.split_on
    epydoc.docstringparser.add_metadata_from_var
    epydoc.docstringparser.check_type_fields
    epydoc.docstringparser.get_docformat
    epydoc.docstringparser.initialize_api_doc
    epydoc.docstringparser.parse_docstring
    epydoc.docstringparser.parse_function_signature
    epydoc.docstringparser.process_arg_field
    epydoc.docstringparser.process_cvar_field
    epydoc.docstringparser.process_deffield_field
    epydoc.docstringparser.process_field
    epydoc.docstringparser.process_group_field
    epydoc.docstringparser.process_include_field
    epydoc.docstringparser.process_ivar_field
    epydoc.docstringparser.process_kwarg_field
    epydoc.docstringparser.process_raise_field
    epydoc.docstringparser.process_return_field
    epydoc.docstringparser.process_rtype_field
    epydoc.docstringparser.process_sort_field
    epydoc.docstringparser.process_summary_field
    epydoc.docstringparser.process_type_field
    epydoc.docstringparser.process_undocumented_field
    epydoc.docstringparser.process_var_field
    epydoc.docstringparser.register_field_handler
    epydoc.docstringparser.report_errors
    epydoc.docstringparser.set_var_descr
    epydoc.docstringparser.set_var_type
    epydoc.docstringparser.split_init_fields
    epydoc.docstringparser.unindent_docstring
    epydoc.docstringparser.user_docfields
    epydoc.docwriter.dotgraph.add_valdoc_nodes
    epydoc.docwriter.dotgraph.call_graph
    epydoc.docwriter.dotgraph.class_tree_graph
    epydoc.docwriter.dotgraph.get_dot_version
    epydoc.docwriter.dotgraph.import_graph
    epydoc.docwriter.dotgraph.name_list
    epydoc.docwriter.dotgraph.package_tree_graph
    epydoc.docwriter.dotgraph.specialize_valdoc_node
    epydoc.docwriter.dotgraph.uml_class_tree_graph
    epydoc.docwriter.dotgraph.uml_package_tree_graph
    epydoc.docwriter.html.compile_template
    epydoc.docwriter.html.strip_indent
    epydoc.docwriter.xlink.create_api_role
    epydoc.docwriter.xlink.register_api
    epydoc.docwriter.xlink.set_api_file
    epydoc.docwriter.xlink.set_api_root
    epydoc.docwriter.xlink.split_name
    epydoc.gui.document
    epydoc.gui.gui
    epydoc.log.close
    epydoc.log.debug
    epydoc.log.docstring_warning
    epydoc.log.end_block
    epydoc.log.end_progress
    epydoc.log.error
    epydoc.log.fatal
    epydoc.log.info
    epydoc.log.progress
    epydoc.log.register_logger
    epydoc.log.remove_logger
    epydoc.log.start_block
    epydoc.log.start_progress
    epydoc.log.warning
    epydoc.markup.doctest.doctest_to_html
    epydoc.markup.doctest.doctest_to_latex
    epydoc.markup.epytext.parse
    epydoc.markup.epytext.parse_as_literal
    epydoc.markup.epytext.parse_as_para
    epydoc.markup.epytext.parse_docstring
    epydoc.markup.epytext.pparse
    epydoc.markup.epytext.to_debug
    epydoc.markup.epytext.to_epytext
    epydoc.markup.epytext.to_plaintext
    epydoc.markup.javadoc.parse_docstring
    epydoc.markup.parse
    epydoc.markup.parse_type_of
    epydoc.markup.plaintext.parse_docstring
    epydoc.markup.pyval_repr.colorize_pyval
    epydoc.markup.pyval_repr.is_re_pattern
    epydoc.markup.register_markup_language
    epydoc.markup.restructuredtext.callgraph_directive
    epydoc.markup.restructuredtext.classtree_directive
    epydoc.markup.restructuredtext.digraph_directive
    epydoc.markup.restructuredtext.importgraph_directive
    epydoc.markup.restructuredtext.latex_head_prefix
    epydoc.markup.restructuredtext.packagetree_directive
    epydoc.markup.restructuredtext.parse_docstring
    epydoc.markup.restructuredtext.python_code_directive
    epydoc.markup.restructuredtext.term_role
    epydoc.test.check_requirements
    epydoc.test.main
    epydoc.test.util.buildvaluedoc
    epydoc.test.util.cleanup_tmp_dir
    epydoc.test.util.fun_to_plain
    epydoc.test.util.print_docstring_as_html
    epydoc.test.util.print_warnings
    epydoc.test.util.remove_surrogates
    epydoc.test.util.runbuilder
    epydoc.test.util.runintrospecter
    epydoc.test.util.runparser
    epydoc.test.util.testencoding
    epydoc.test.util.to_plain
    epydoc.test.util.write_pystring_to_tmp_dir
    epydoc.util.decode_with_backslashreplace
    epydoc.util.is_module_file
    epydoc.util.is_package_dir
    epydoc.util.is_pyname
    epydoc.util.is_src_filename
    epydoc.util.munge_script_name
    epydoc.util.plaintext_to_html
    epydoc.util.plaintext_to_latex
    epydoc.util.py_src_filename
    epydoc.util.run_subprocess
    epydoc.util.wordwrap

    All Variables

    epydoc.DEBUG
    epydoc.__author__
    epydoc.__license__
    epydoc.__url__
    epydoc.__version__
    epydoc.apidoc.UNKNOWN
    epydoc.cli.ACTIONS
    epydoc.cli.DEFAULT_DOCFORMAT
    epydoc.cli.DOCFORMATS
    epydoc.cli.GRAPH_TYPES
    epydoc.cli.HELP_TOPICS
    epydoc.cli.INHERITANCE_STYLES
    epydoc.cli.OPTION_DEFAULTS
    epydoc.cli.PROFILER
    epydoc.cli.descr
    epydoc.cli.key
    epydoc.cli.sheet
    epydoc.cli.topic
    epydoc.docbuilder.DEFAULT_MERGE_PRECEDENCE
    epydoc.docbuilder.MERGE_PRECEDENCE
    epydoc.docintrospecter.UNDOCUMENTED_CLASS_VARS
    epydoc.docintrospecter.UNDOCUMENTED_MODULE_VARS
    epydoc.docparser.BASE_HANDLING
    epydoc.docparser.COMMENT_DOCSTRING_MARKER
    epydoc.docparser.CONTROL_FLOW_KEYWORDS
    epydoc.docparser.DEFAULT_DECORATOR_BEHAVIOR
    epydoc.docparser.END_GROUP_MARKER
    epydoc.docparser.IMPORT_HANDLING
    epydoc.docparser.IMPORT_STAR_HANDLING
    epydoc.docparser.PARSE_ELSE_BLOCKS
    epydoc.docparser.PARSE_EXCEPT_BLOCKS
    epydoc.docparser.PARSE_FINALLY_BLOCKS
    epydoc.docparser.PARSE_FOR_BLOCKS
    epydoc.docparser.PARSE_IF_BLOCKS
    epydoc.docparser.PARSE_TRY_BLOCKS
    epydoc.docparser.PARSE_WHILE_BLOCKS
    epydoc.docparser.START_GROUP_MARKER
    epydoc.docstringparser.BAD_CONTEXT
    epydoc.docstringparser.BAD_PARAM
    epydoc.docstringparser.DEFAULT_DOCFORMAT
    epydoc.docstringparser.EXCEPTION_TAGS
    epydoc.docstringparser.EXPECTED_ARG
    epydoc.docstringparser.EXPECTED_SINGLE_ARG
    epydoc.docstringparser.PARAMETER_TAGS
    epydoc.docstringparser.REDEFINED
    epydoc.docstringparser.RETURN_PDS
    epydoc.docstringparser.STANDARD_FIELDS
    epydoc.docstringparser.UNEXPECTED_ARG
    epydoc.docstringparser.UNKNOWN_TAG
    epydoc.docstringparser.VARIABLE_TAGS
    epydoc.docwriter.dotgraph.BASECLASS_BG
    epydoc.docwriter.dotgraph.CLASS_BG
    epydoc.docwriter.dotgraph.DOT_COMMAND
    epydoc.docwriter.dotgraph.INH_LINK_COLOR
    epydoc.docwriter.dotgraph.MODULE_BG
    epydoc.docwriter.dotgraph.MODULE_NODE_HTML
    epydoc.docwriter.dotgraph.NOOP_URL
    epydoc.docwriter.dotgraph.ROUTINE_BG
    epydoc.docwriter.dotgraph.SELECTED_BG
    epydoc.docwriter.dotgraph.SUBCLASS_BG
    epydoc.docwriter.html_colorize.PYSRC_EXPANDTO_JAVASCRIPT
    epydoc.docwriter.html_colorize.PYSRC_JAVASCRIPTS
    epydoc.docwriter.html_css.STYLESHEETS
    epydoc.docwriter.html_css.TEMPLATE
    epydoc.docwriter.html_help.HTML_HELP
    epydoc.docwriter.xlink.api_register
    epydoc.gui.ACTIVEBG_COLOR
    epydoc.gui.BG_COLOR
    epydoc.gui.BUILD_PROGRESS
    epydoc.gui.BUTTON_CONFIG
    epydoc.gui.CBUTTON_CONFIG
    epydoc.gui.COLOR_CONFIG
    epydoc.gui.DEBUG
    epydoc.gui.DH
    epydoc.gui.DOWN_GIF
    epydoc.gui.DW
    epydoc.gui.DX
    epydoc.gui.DY
    epydoc.gui.ENTRYSELECT_COLOR
    epydoc.gui.ENTRY_CONFIG
    epydoc.gui.ERROR_COLOR
    epydoc.gui.GUIERROR_COLOR
    epydoc.gui.HEADER_COLOR
    epydoc.gui.IMPORT_PROGRESS
    epydoc.gui.LEFT_GIF
    epydoc.gui.LISTBOX_CONFIG
    epydoc.gui.MESSAGE_COLOR
    epydoc.gui.PROGRESS_BG
    epydoc.gui.PROGRESS_COLOR1
    epydoc.gui.PROGRESS_COLOR2
    epydoc.gui.PROGRESS_COLOR3
    epydoc.gui.PROGRESS_HEIGHT
    epydoc.gui.PROGRESS_WIDTH
    epydoc.gui.RIGHT_GIF
    epydoc.gui.SB_CONFIG
    epydoc.gui.SELECT_COLOR
    epydoc.gui.SHOWERR_CONFIG
    epydoc.gui.SHOWMSG_CONFIG
    epydoc.gui.SHOWWRN_CONFIG
    epydoc.gui.TEXT_COLOR
    epydoc.gui.UP_GIF
    epydoc.gui.WARNING_COLOR
    epydoc.gui.WRITE_PROGRESS
    epydoc.log.DEBUG
    epydoc.log.DOCSTRING_WARNING
    epydoc.log.ERROR
    epydoc.log.FATAL
    epydoc.log.INFO
    epydoc.log.WARNING
    epydoc.markup.MARKUP_LANGUAGES_USED
    epydoc.markup.SCRWIDTH
    epydoc.markup.epytext.GRAPH_TYPES
    epydoc.markup.epytext.SYMBOLS
    epydoc.markup.epytext.SYMBOL_TO_PLAINTEXT
    epydoc.markup.epytext.__doc__
    epydoc.markup.restructuredtext.CONSOLIDATED_DEFLIST_FIELDS
    epydoc.markup.restructuredtext.CONSOLIDATED_FIELDS
    epydoc.util.PY_BIN_EXTENSIONS
    epydoc.util.PY_SRC_EXTENSIONS

    [hide private] epydoc-3.0.1+dfsg/doc/api/module-tree.html0000644000175000017500000002411210750103050020612 0ustar pronovicpronovic Module Hierarchy
     
    [hide private]
    [frames] | no frames]
    [ Module Hierarchy | Class Hierarchy ]

    Module Hierarchy

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr-module.html0000644000175000017500000003067710750103050024633 0ustar pronovicpronovic epydoc.markup.pyval_repr
    Package epydoc :: Package markup :: Module pyval_repr
    [hide private]
    [frames] | no frames]

    Module pyval_repr

    source code

    Syntax highlighter for Python values. Currently provides special colorization support for:

    • lists, tuples, sets, frozensets, dicts
    • numbers
    • strings
    • compiled regexps

    The highlighter also takes care of line-wrapping, and automatically stops generating repr output as soon as it has exceeded the specified number of lines (which should make it faster than pprint for large values). It does not bother to do automatic cycle detection, because maxlines is typically around 5, so it's really not worth it.

    The syntax-highlighted output is encoded using a ParsedEpytextDocstring, which can then be used to generate output in a variety of formats.

    Classes [hide private]
      _ColorizerState
    An object uesd to keep track of the current state of the pyval colorizer.
      _Maxlines
    A control-flow exception that is raised when PyvalColorizer exeeds the maximum number of allowed lines.
      _Linebreak
    A control-flow exception that is raised when PyvalColorizer generates a string containing a newline, but the state object's linebreakok variable is False.
      ColorizedPyvalRepr
      PyvalColorizer
    Syntax highlighter for Python values.
    Functions [hide private]
     
    is_re_pattern(pyval) source code
    call graph 
     
    colorize_pyval(pyval, parse_repr=None, min_score=None, linelen=75, maxlines=5, linebreakok=True, sort=True) source code
    call graph 
    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.doctest-module.html0000644000175000017500000000332110750103050024662 0ustar pronovicpronovic doctest

    Module doctest


    Classes

    DoctestColorizer
    HTMLDoctestColorizer
    LaTeXDoctestColorizer
    XMLDoctestColorizer

    Functions

    doctest_to_html
    doctest_to_latex

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.plaintext-pysrc.html0000644000175000017500000011137610750103050024327 0ustar pronovicpronovic epydoc.markup.plaintext
    Package epydoc :: Package markup :: Module plaintext
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.markup.plaintext

     1  # 
     2  # plaintext.py: plaintext docstring parsing 
     3  # Edward Loper 
     4  # 
     5  # Created [04/10/01 12:00 AM] 
     6  # $Id: plaintext.py 1574 2007-03-07 02:55:14Z dvarrazzo $ 
     7  # 
     8   
     9  """ 
    10  Parser for plaintext docstrings.  Plaintext docstrings are rendered as 
    11  verbatim output, preserving all whitespace. 
    12  """ 
    13  __docformat__ = 'epytext en' 
    14   
    15  from epydoc.markup import * 
    16  from epydoc.util import plaintext_to_html, plaintext_to_latex 
    17   
    
    18 -def parse_docstring(docstring, errors, **options):
    19 """ 20 @return: A pair C{(M{d}, M{e})}, where C{M{d}} is a 21 C{ParsedDocstring} that encodes the contents of the given 22 plaintext docstring; and C{M{e}} is a list of errors that were 23 generated while parsing the docstring. 24 @rtype: C{L{ParsedPlaintextDocstring}, C{list} of L{ParseError}} 25 """ 26 return ParsedPlaintextDocstring(docstring, **options)
    27
    28 -class ParsedPlaintextDocstring(ParsedDocstring):
    29 - def __init__(self, text, **options):
    30 self._verbatim = options.get('verbatim', 1) 31 if text is None: raise ValueError, 'Bad text value (expected a str)' 32 self._text = text
    33
    34 - def to_html(self, docstring_linker, **options):
    35 if options.get('verbatim', self._verbatim) == 0: 36 return plaintext_to_html(self.to_plaintext(docstring_linker)) 37 else: 38 return ParsedDocstring.to_html(self, docstring_linker, **options)
    39
    40 - def to_latex(self, docstring_linker, **options):
    41 if options.get('verbatim', self._verbatim) == 0: 42 return plaintext_to_latex(self.to_plaintext(docstring_linker)) 43 else: 44 return ParsedDocstring.to_latex(self, docstring_linker, **options)
    45
    46 - def to_plaintext(self, docstring_linker, **options):
    47 if 'indent' in options: 48 indent = options['indent'] 49 lines = self._text.split('\n') 50 return '\n'.join([' '*indent+l for l in lines])+'\n' 51 return self._text+'\n'
    52 53 _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?(?:\.(\s|$)|[\n][\t ]*[\n]))') 54
    55 - def summary(self):
    56 m = self._SUMMARY_RE.match(self._text) 57 if m: 58 other = self._text[m.end():] 59 return (ParsedPlaintextDocstring(m.group(1), verbatim=0), 60 other != '' and not other.isspace()) 61 else: 62 parts = self._text.strip('\n').split('\n', 1) 63 if len(parts) == 1: 64 summary = parts[0] 65 other = False 66 else: 67 summary = parts[0] + '...' 68 other = True 69 70 return ParsedPlaintextDocstring(summary, verbatim=0), other
    71 72 # def concatenate(self, other): 73 # if not isinstance(other, ParsedPlaintextDocstring): 74 # raise ValueError, 'Could not concatenate docstrings' 75 # text = self._text+other._text 76 # options = self._options.copy() 77 # options.update(other._options) 78 # return ParsedPlaintextDocstring(text, options) 79

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.plaintext-module.html0000644000175000017500000000214010750103050025726 0ustar pronovicpronovic plaintext

    Module plaintext


    Classes

    PlaintextWriter

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext.dotgraph-class.html0000644000175000017500000005737210750103050027540 0ustar pronovicpronovic epydoc.markup.restructuredtext.dotgraph
    Package epydoc :: Package markup :: Module restructuredtext :: Class dotgraph
    [hide private]
    [frames] | no frames]

    Class dotgraph

    source code


    A custom docutils node that should be rendered using Graphviz dot. This node does not directly store the graph; instead, it stores a pointer to a function that can be used to generate the graph. This allows the graph to be built based on information that might not be available yet at parse time. This graph generation function has the following signature:

    >>> def generate_graph(docindex, context, linker, *args):
    ...     'generates and returns a new DotGraph'

    Where docindex is a docindex containing the documentation that epydoc has built; context is the APIDoc whose docstring contains this dotgraph node; linker is a DocstringLinker that can be used to resolve crossreferences; and args is any extra arguments that are passed to the dotgraph constructor.

    Instance Methods [hide private]
     
    __init__(self, generate_graph_func, *generate_graph_args) source code
    call graph 
     
    graph(self, docindex, context, linker) source code
    call graph 

    Inherited from docutils.nodes.image: astext

    Inherited from docutils.nodes.Element: __add__, __delitem__, __getitem__, __iadd__, __len__, __radd__, __repr__, __setitem__, __unicode__, append, attlist, clear, copy, deepcopy, delattr, emptytag, endtag, extend, first_child_matching_class, first_child_not_matching_class, get, has_key, hasattr, index, insert, is_not_default, non_default_attributes, note_referenced_by, pformat, pop, remove, replace, replace_self, set_class, setdefault, shortrepr, starttag, update_basic_atts

    Inherited from docutils.nodes.Element (private): _dom_node

    Inherited from docutils.nodes.Node: __nonzero__, __str__, asdom, next_node, setup_child, traverse, walk, walkabout

    Class Variables [hide private]

    Inherited from docutils.nodes.Element: child_text_separator, list_attributes, tagname

    Inherited from docutils.nodes.Node: document, line, parent, source

    Instance Variables [hide private]

    Inherited from docutils.nodes.Element: attributes, children, rawsource

    Method Details [hide private]

    __init__(self, generate_graph_func, *generate_graph_args)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.nodes.Element.__init__

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.html_colorize-module.html0000644000175000017500000000326510750103050026601 0ustar pronovicpronovic html_colorize

    Module html_colorize


    Classes

    PythonSourceColorizer

    Variables

    PYSRC_EXPANDTO_JAVASCRIPT
    PYSRC_JAVASCRIPTS

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.ParseError-class.html0000644000175000017500000006234110750103050024345 0ustar pronovicpronovic epydoc.markup.ParseError
    Package epydoc :: Package markup :: Class ParseError
    [hide private]
    [frames] | no frames]

    Class ParseError

    source code


    The base class for errors generated while parsing docstrings.

    Instance Methods [hide private]
     
    __init__(self, descr, linenum=None, is_fatal=1) source code
    boolean
    is_fatal(self)
    Returns: true if this is a fatal error.
    source code
    int or None
    linenum(self)
    Returns: The line number on which the error occured (including any offset).
    source code
    None
    set_linenum_offset(self, offset)
    Set the line number offset for this error.
    source code
     
    descr(self) source code
    string
    __str__(self)
    Return a string representation of this ParseError.
    source code
    string
    __repr__(self)
    Return the formal representation of this ParseError.
    source code
    int
    __cmp__(self, other)
    Compare two ParseErrors, based on their line number.
    source code

    Inherited from exceptions.Exception: __getitem__

    Instance Variables [hide private]
    string _descr
    A description of the error.
    boolean _fatal
    True if this is a fatal error.
    int _linenum
    The line on which the error occured within the docstring.
    int _offset
    The line number where the docstring begins.
    Method Details [hide private]

    __init__(self, descr, linenum=None, is_fatal=1)
    (Constructor)

    source code 
    Parameters:
    • descr (string) - A description of the error.
    • linenum (int) - The line on which the error occured within the docstring. The linenum of the first line is 0.
    • is_fatal (boolean) - True if this is a fatal error.
    Overrides: exceptions.Exception.__init__

    is_fatal(self)

    source code 
    Returns: boolean
    true if this is a fatal error. If an error is fatal, then epydoc should ignore the output of the parser, and parse the docstring as plaintext.

    linenum(self)

    source code 
    Returns: int or None
    The line number on which the error occured (including any offset). If the line number is unknown, then return None.

    set_linenum_offset(self, offset)

    source code 

    Set the line number offset for this error. This offset is the line number where the docstring begins. This offset is added to _linenum when displaying the line number of the error.

    Parameters:
    • offset (int) - The new line number offset.
    Returns: None

    __str__(self)
    (Informal representation operator)

    source code 

    Return a string representation of this ParseError. This multi-line string contains a description of the error, and specifies where it occured.

    Returns: string
    the informal representation of this ParseError.
    Overrides: exceptions.Exception.__str__

    __repr__(self)
    (Representation operator)

    source code 

    Return the formal representation of this ParseError. ParseErrors have formal representations of the form:

      <ParseError on line 12>
    
    Returns: string
    the formal representation of this ParseError.

    __cmp__(self, other)
    (Comparison operator)

    source code 

    Compare two ParseErrors, based on their line number.

    • Return -1 if self.linenum<other.linenum
    • Return +1 if self.linenum>other.linenum
    • Return 0 if self.linenum==other.linenum.

    The return value is undefined if other is not a ParseError.

    Returns: int

    Instance Variable Details [hide private]

    _linenum

    The line on which the error occured within the docstring. The linenum of the first line is 0.
    Type:
    int

    _offset

    The line number where the docstring begins. This offset is added to _linenum when displaying the line number of the error. Default value: 1.
    Type:
    int

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.test.util-module.html0000644000175000017500000000436010750103050023656 0ustar pronovicpronovic util

    Module util


    Functions

    buildvaluedoc
    cleanup_tmp_dir
    fun_to_plain
    print_docstring_as_html
    print_warnings
    remove_surrogates
    runbuilder
    runintrospecter
    runparser
    testencoding
    to_plain
    write_pystring_to_tmp_dir

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.latex-pysrc.html0000644000175000017500000150147410750103050024142 0ustar pronovicpronovic epydoc.docwriter.latex
    Package epydoc :: Package docwriter :: Module latex
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.latex

       1  # 
       2  # epydoc.py: epydoc LaTeX output generator 
       3  # Edward Loper 
       4  # 
       5  # Created [01/30/01 05:18 PM] 
       6  # $Id: latex.py 1621 2007-09-23 18:54:23Z edloper $ 
       7  # 
       8   
       9  """ 
      10  The LaTeX output generator for epydoc.  The main interface provided by 
      11  this module is the L{LatexWriter} class. 
      12   
      13  @todo: Inheritance=listed 
      14  """ 
      15  __docformat__ = 'epytext en' 
      16   
      17  import os.path, sys, time, re, textwrap, codecs 
      18   
      19  from epydoc.apidoc import * 
      20  from epydoc.compat import * 
      21  import epydoc 
      22  from epydoc import log 
      23  from epydoc import markup 
      24  from epydoc.util import plaintext_to_latex 
      25  import epydoc.markup 
      26   
    
    27 -class LatexWriter:
    28 PREAMBLE = [ 29 "\\documentclass{article}", 30 "\\usepackage{alltt, parskip, fancyhdr, boxedminipage}", 31 "\\usepackage{makeidx, multirow, longtable, tocbibind, amssymb}", 32 "\\usepackage{fullpage}", 33 "\\usepackage[usenames]{color}", 34 # Fix the heading position -- without this, the headings generated 35 # by the fancyheadings package sometimes overlap the text. 36 "\\setlength{\\headheight}{16pt}", 37 "\\setlength{\\headsep}{24pt}", 38 "\\setlength{\\topmargin}{-\\headsep}", 39 # By default, do not indent paragraphs. 40 "\\setlength{\\parindent}{0ex}", 41 "\\setlength{\\parskip}{2ex}", 42 # Double the standard size boxedminipage outlines. 43 "\\setlength{\\fboxrule}{2\\fboxrule}", 44 # Create a 'base class' length named BCL for use in base trees. 45 "\\newlength{\\BCL} % base class length, for base trees.", 46 # Display the section & subsection names in a header. 47 "\\pagestyle{fancy}", 48 "\\renewcommand{\\sectionmark}[1]{\\markboth{#1}{}}", 49 "\\renewcommand{\\subsectionmark}[1]{\\markright{#1}}", 50 # Colorization for python source code 51 "\\definecolor{py@keywordcolour}{rgb}{1,0.45882,0}", 52 "\\definecolor{py@stringcolour}{rgb}{0,0.666666,0}", 53 "\\definecolor{py@commentcolour}{rgb}{1,0,0}", 54 "\\definecolor{py@ps1colour}{rgb}{0.60784,0,0}", 55 "\\definecolor{py@ps2colour}{rgb}{0.60784,0,1}", 56 "\\definecolor{py@inputcolour}{rgb}{0,0,0}", 57 "\\definecolor{py@outputcolour}{rgb}{0,0,1}", 58 "\\definecolor{py@exceptcolour}{rgb}{1,0,0}", 59 "\\definecolor{py@defnamecolour}{rgb}{1,0.5,0.5}", 60 "\\definecolor{py@builtincolour}{rgb}{0.58039,0,0.58039}", 61 "\\definecolor{py@identifiercolour}{rgb}{0,0,0}", 62 "\\definecolor{py@linenumcolour}{rgb}{0.4,0.4,0.4}", 63 "\\definecolor{py@inputcolour}{rgb}{0,0,0}", 64 "% Prompt", 65 "\\newcommand{\\pysrcprompt}[1]{\\textcolor{py@ps1colour}" 66 "{\\small\\textbf{#1}}}", 67 "\\newcommand{\\pysrcmore}[1]{\\textcolor{py@ps2colour}" 68 "{\\small\\textbf{#1}}}", 69 "% Source code", 70 "\\newcommand{\\pysrckeyword}[1]{\\textcolor{py@keywordcolour}" 71 "{\\small\\textbf{#1}}}", 72 "\\newcommand{\\pysrcbuiltin}[1]{\\textcolor{py@builtincolour}" 73 "{\\small\\textbf{#1}}}", 74 "\\newcommand{\\pysrcstring}[1]{\\textcolor{py@stringcolour}" 75 "{\\small\\textbf{#1}}}", 76 "\\newcommand{\\pysrcdefname}[1]{\\textcolor{py@defnamecolour}" 77 "{\\small\\textbf{#1}}}", 78 "\\newcommand{\\pysrcother}[1]{\\small\\textbf{#1}}", 79 "% Comments", 80 "\\newcommand{\\pysrccomment}[1]{\\textcolor{py@commentcolour}" 81 "{\\small\\textbf{#1}}}", 82 "% Output", 83 "\\newcommand{\\pysrcoutput}[1]{\\textcolor{py@outputcolour}" 84 "{\\small\\textbf{#1}}}", 85 "% Exceptions", 86 "\\newcommand{\\pysrcexcept}[1]{\\textcolor{py@exceptcolour}" 87 "{\\small\\textbf{#1}}}", 88 # Size of the function description boxes. 89 "\\newlength{\\funcindent}", 90 "\\newlength{\\funcwidth}", 91 "\\setlength{\\funcindent}{1cm}", 92 "\\setlength{\\funcwidth}{\\textwidth}", 93 "\\addtolength{\\funcwidth}{-2\\funcindent}", 94 # Size of the var description tables. 95 "\\newlength{\\varindent}", 96 "\\newlength{\\varnamewidth}", 97 "\\newlength{\\vardescrwidth}", 98 "\\newlength{\\varwidth}", 99 "\\setlength{\\varindent}{1cm}", 100 "\\setlength{\\varnamewidth}{.3\\textwidth}", 101 "\\setlength{\\varwidth}{\\textwidth}", 102 "\\addtolength{\\varwidth}{-4\\tabcolsep}", 103 "\\addtolength{\\varwidth}{-3\\arrayrulewidth}", 104 "\\addtolength{\\varwidth}{-2\\varindent}", 105 "\\setlength{\\vardescrwidth}{\\varwidth}", 106 "\\addtolength{\\vardescrwidth}{-\\varnamewidth}", 107 # Define new environment for displaying parameter lists. 108 textwrap.dedent("""\ 109 \\newenvironment{Ventry}[1]% 110 {\\begin{list}{}{% 111 \\renewcommand{\\makelabel}[1]{\\texttt{##1:}\\hfil}% 112 \\settowidth{\\labelwidth}{\\texttt{#1:}}% 113 \\setlength{\\leftmargin}{\\labelsep}% 114 \\addtolength{\\leftmargin}{\\labelwidth}}}% 115 {\\end{list}}"""), 116 ] 117 118 HRULE = '\\rule{\\textwidth}{0.5\\fboxrule}\n\n' 119 120 SECTIONS = ['\\part{%s}', '\\chapter{%s}', '\\section{%s}', 121 '\\subsection{%s}', '\\subsubsection{%s}', 122 '\\textbf{%s}'] 123 124 STAR_SECTIONS = ['\\part*{%s}', '\\chapter*{%s}', '\\section*{%s}', 125 '\\subsection*{%s}', '\\subsubsection*{%s}', 126 '\\textbf{%s}'] 127
    128 - def __init__(self, docindex, **kwargs):
    129 self.docindex = docindex 130 # Process keyword arguments 131 self._show_private = kwargs.get('private', 0) 132 self._prj_name = kwargs.get('prj_name', None) or 'API Documentation' 133 self._crossref = kwargs.get('crossref', 1) 134 self._index = kwargs.get('index', 1) 135 self._list_classes_separately=kwargs.get('list_classes_separately',0) 136 self._inheritance = kwargs.get('inheritance', 'listed') 137 self._exclude = kwargs.get('exclude', 1) 138 self._top_section = 2 139 self._index_functions = 1 140 self._hyperref = 1 141 142 #: The Python representation of the encoding. 143 #: Update L{latex_encodings} in case of mismatch between it and 144 #: the C{inputenc} LaTeX package. 145 self._encoding = kwargs.get('encoding', 'utf-8') 146 147 self.valdocs = valdocs = sorted(docindex.reachable_valdocs( 148 imports=False, packages=False, bases=False, submodules=False, 149 subclasses=False, private=self._show_private)) 150 self._num_files = self.num_files() 151 # For use with select_variables(): 152 if self._show_private: self._public_filter = None 153 else: self._public_filter = True 154 155 self.class_list = [d for d in valdocs if isinstance(d, ClassDoc)] 156 """The list of L{ClassDoc}s for the documented classes.""" 157 self.class_set = set(self.class_list) 158 """The set of L{ClassDoc}s for the documented classes."""
    159
    160 - def write(self, directory=None):
    161 """ 162 Write the API documentation for the entire project to the 163 given directory. 164 165 @type directory: C{string} 166 @param directory: The directory to which output should be 167 written. If no directory is specified, output will be 168 written to the current directory. If the directory does 169 not exist, it will be created. 170 @rtype: C{None} 171 @raise OSError: If C{directory} cannot be created, 172 @raise OSError: If any file cannot be created or written to. 173 """ 174 # For progress reporting: 175 self._files_written = 0. 176 177 # Set the default values for ValueDoc formatted representations. 178 orig_valdoc_defaults = (ValueDoc.SUMMARY_REPR_LINELEN, 179 ValueDoc.REPR_LINELEN, 180 ValueDoc.REPR_MAXLINES) 181 ValueDoc.SUMMARY_REPR_LINELEN = 60 182 ValueDoc.REPR_LINELEN = 52 183 ValueDoc.REPR_MAXLINES = 5 184 185 # Create destination directories, if necessary 186 if not directory: directory = os.curdir 187 self._mkdir(directory) 188 self._directory = directory 189 190 # Write the top-level file. 191 self._write(self.write_topfile, directory, 'api.tex') 192 193 # Write the module & class files. 194 for val_doc in self.valdocs: 195 if isinstance(val_doc, ModuleDoc): 196 filename = '%s-module.tex' % val_doc.canonical_name 197 self._write(self.write_module, directory, filename, val_doc) 198 elif (isinstance(val_doc, ClassDoc) and 199 self._list_classes_separately): 200 filename = '%s-class.tex' % val_doc.canonical_name 201 self._write(self.write_class, directory, filename, val_doc) 202 203 # Restore defaults that we changed. 204 (ValueDoc.SUMMARY_REPR_LINELEN, ValueDoc.REPR_LINELEN, 205 ValueDoc.REPR_MAXLINES) = orig_valdoc_defaults
    206
    207 - def _write(self, write_func, directory, filename, *args):
    208 # Display our progress. 209 self._files_written += 1 210 log.progress(self._files_written/self._num_files, filename) 211 212 path = os.path.join(directory, filename) 213 if self._encoding == 'utf-8': 214 f = codecs.open(path, 'w', 'utf-8') 215 write_func(f.write, *args) 216 f.close() 217 else: 218 result = [] 219 write_func(result.append, *args) 220 s = u''.join(result) 221 try: 222 s = s.encode(self._encoding) 223 except UnicodeError: 224 log.error("Output could not be represented with the " 225 "given encoding (%r). Unencodable characters " 226 "will be displayed as '?'. It is recommended " 227 "that you use a different output encoding (utf-8, " 228 "if it's supported by latex on your system)." 229 % self._encoding) 230 s = s.encode(self._encoding, 'replace') 231 f = open(path, 'w') 232 f.write(s) 233 f.close()
    234
    235 - def num_files(self):
    236 """ 237 @return: The number of files that this C{LatexFormatter} will 238 generate. 239 @rtype: C{int} 240 """ 241 n = 1 242 for doc in self.valdocs: 243 if isinstance(doc, ModuleDoc): n += 1 244 if isinstance(doc, ClassDoc) and self._list_classes_separately: 245 n += 1 246 return n
    247
    248 - def _mkdir(self, directory):
    249 """ 250 If the given directory does not exist, then attempt to create it. 251 @rtype: C{None} 252 """ 253 if not os.path.isdir(directory): 254 if os.path.exists(directory): 255 raise OSError('%r is not a directory' % directory) 256 os.mkdir(directory)
    257 258 #//////////////////////////////////////////////////////////// 259 #{ Main Doc File 260 #//////////////////////////////////////////////////////////// 261
    262 - def write_topfile(self, out):
    263 self.write_header(out, 'Include File') 264 self.write_preamble(out) 265 out('\n\\begin{document}\n\n') 266 self.write_start_of(out, 'Header') 267 268 # Write the title. 269 self.write_start_of(out, 'Title') 270 out('\\title{%s}\n' % plaintext_to_latex(self._prj_name, 1)) 271 out('\\author{API Documentation}\n') 272 out('\\maketitle\n') 273 274 # Add a table of contents. 275 self.write_start_of(out, 'Table of Contents') 276 out('\\addtolength{\\parskip}{-2ex}\n') 277 out('\\tableofcontents\n') 278 out('\\addtolength{\\parskip}{2ex}\n') 279 280 # Include documentation files. 281 self.write_start_of(out, 'Includes') 282 for val_doc in self.valdocs: 283 if isinstance(val_doc, ModuleDoc): 284 out('\\include{%s-module}\n' % val_doc.canonical_name) 285 286 # If we're listing classes separately, put them after all the 287 # modules. 288 if self._list_classes_separately: 289 for val_doc in self.valdocs: 290 if isinstance(val_doc, ClassDoc): 291 out('\\include{%s-class}\n' % val_doc.canonical_name) 292 293 # Add the index, if requested. 294 if self._index: 295 self.write_start_of(out, 'Index') 296 out('\\printindex\n\n') 297 298 # Add the footer. 299 self.write_start_of(out, 'Footer') 300 out('\\end{document}\n\n')
    301
    302 - def write_preamble(self, out):
    303 out('\n'.join(self.PREAMBLE)) 304 out('\n') 305 306 # Set the encoding. 307 out('\\usepackage[%s]{inputenc}\n' % self.get_latex_encoding()) 308 309 # If we're generating hyperrefs, add the appropriate packages. 310 if self._hyperref: 311 out('\\definecolor{UrlColor}{rgb}{0,0.08,0.45}\n') 312 out('\\usepackage[dvips, pagebackref, pdftitle={%s}, ' 313 'pdfcreator={epydoc %s}, bookmarks=true, ' 314 'bookmarksopen=false, pdfpagemode=UseOutlines, ' 315 'colorlinks=true, linkcolor=black, anchorcolor=black, ' 316 'citecolor=black, filecolor=black, menucolor=black, ' 317 'pagecolor=black, urlcolor=UrlColor]{hyperref}\n' % 318 (self._prj_name or '', epydoc.__version__)) 319 320 # If we're generating an index, add it to the preamble. 321 if self._index: 322 out("\\makeindex\n") 323 324 # If restructuredtext was used, then we need to extend 325 # the prefix to include LatexTranslator.head_prefix. 326 if 'restructuredtext' in epydoc.markup.MARKUP_LANGUAGES_USED: 327 from epydoc.markup import restructuredtext 328 rst_head = restructuredtext.latex_head_prefix() 329 rst_head = ''.join(rst_head).split('\n') 330 for line in rst_head[1:]: 331 m = re.match(r'\\usepackage(\[.*?\])?{(.*?)}', line) 332 if m and m.group(2) in ( 333 'babel', 'hyperref', 'color', 'alltt', 'parskip', 334 'fancyhdr', 'boxedminipage', 'makeidx', 335 'multirow', 'longtable', 'tocbind', 'assymb', 336 'fullpage', 'inputenc'): 337 pass 338 else: 339 out(line+'\n')
    340 341 342 #//////////////////////////////////////////////////////////// 343 #{ Chapters 344 #//////////////////////////////////////////////////////////// 345
    346 - def write_module(self, out, doc):
    347 self.write_header(out, doc) 348 self.write_start_of(out, 'Module Description') 349 350 # Add this module to the index. 351 out(' ' + self.indexterm(doc, 'start')) 352 353 # Add a section marker. 354 out(self.section('%s %s' % (self.doc_kind(doc), 355 doc.canonical_name))) 356 357 # Label our current location. 358 out(' \\label{%s}\n' % self.label(doc)) 359 360 # Add the module's description. 361 if doc.descr not in (None, UNKNOWN): 362 out(self.docstring_to_latex(doc.descr)) 363 364 # Add version, author, warnings, requirements, notes, etc. 365 self.write_standard_fields(out, doc) 366 367 # If it's a package, list the sub-modules. 368 if doc.submodules != UNKNOWN and doc.submodules: 369 self.write_module_list(out, doc) 370 371 # Contents. 372 if self._list_classes_separately: 373 self.write_class_list(out, doc) 374 self.write_func_list(out, 'Functions', doc, 'function') 375 self.write_var_list(out, 'Variables', doc, 'other') 376 377 # Class list. 378 if not self._list_classes_separately: 379 classes = doc.select_variables(imported=False, value_type='class', 380 public=self._public_filter) 381 for var_doc in classes: 382 self.write_class(out, var_doc.value) 383 384 # Mark the end of the module (for the index) 385 out(' ' + self.indexterm(doc, 'end'))
    386
    387 - def write_class(self, out, doc):
    388 if self._list_classes_separately: 389 self.write_header(out, doc) 390 self.write_start_of(out, 'Class Description') 391 392 # Add this class to the index. 393 out(' ' + self.indexterm(doc, 'start')) 394 395 # Add a section marker. 396 if self._list_classes_separately: 397 seclevel = 0 398 out(self.section('%s %s' % (self.doc_kind(doc), 399 doc.canonical_name), seclevel)) 400 else: 401 seclevel = 1 402 out(self.section('%s %s' % (self.doc_kind(doc), 403 doc.canonical_name[-1]), seclevel)) 404 405 # Label our current location. 406 out(' \\label{%s}\n' % self.label(doc)) 407 408 # Add our base list. 409 if doc.bases not in (UNKNOWN, None) and len(doc.bases) > 0: 410 out(self.base_tree(doc)) 411 412 # The class's known subclasses 413 if doc.subclasses not in (UNKNOWN, None) and len(doc.subclasses) > 0: 414 sc_items = [plaintext_to_latex('%s' % sc.canonical_name) 415 for sc in doc.subclasses] 416 out(self._descrlist(sc_items, 'Known Subclasses', short=1)) 417 418 # The class's description. 419 if doc.descr not in (None, UNKNOWN): 420 out(self.docstring_to_latex(doc.descr)) 421 422 # Version, author, warnings, requirements, notes, etc. 423 self.write_standard_fields(out, doc) 424 425 # Contents. 426 self.write_func_list(out, 'Methods', doc, 'method', 427 seclevel+1) 428 self.write_var_list(out, 'Properties', doc, 429 'property', seclevel+1) 430 self.write_var_list(out, 'Class Variables', doc, 431 'classvariable', seclevel+1) 432 self.write_var_list(out, 'Instance Variables', doc, 433 'instancevariable', seclevel+1) 434 435 # Mark the end of the class (for the index) 436 out(' ' + self.indexterm(doc, 'end'))
    437 438 #//////////////////////////////////////////////////////////// 439 #{ Module hierarchy trees 440 #//////////////////////////////////////////////////////////// 441
    442 - def write_module_tree(self, out):
    443 modules = [doc for doc in self.valdocs 444 if isinstance(doc, ModuleDoc)] 445 if not modules: return 446 447 # Write entries for all top-level modules/packages. 448 out('\\begin{itemize}\n') 449 out('\\setlength{\\parskip}{0ex}\n') 450 for doc in modules: 451 if (doc.package in (None, UNKNOWN) or 452 doc.package not in self.valdocs): 453 self.write_module_tree_item(out, doc) 454 return s +'\\end{itemize}\n'
    455
    456 - def write_module_list(self, out, doc):
    457 if len(doc.submodules) == 0: return 458 self.write_start_of(out, 'Modules') 459 460 out(self.section('Modules', 1)) 461 out('\\begin{itemize}\n') 462 out('\\setlength{\\parskip}{0ex}\n') 463 464 for group_name in doc.group_names(): 465 if not doc.submodule_groups[group_name]: continue 466 if group_name: 467 out(' \\item \\textbf{%s}\n' % group_name) 468 out(' \\begin{itemize}\n') 469 for submodule in doc.submodule_groups[group_name]: 470 self.write_module_tree_item(out, submodule) 471 if group_name: 472 out(' \end{itemize}\n') 473 474 out('\\end{itemize}\n\n')
    475
    476 - def write_module_tree_item(self, out, doc, depth=0):
    477 """ 478 Helper function for L{write_module_tree} and L{write_module_list}. 479 480 @rtype: C{string} 481 """ 482 out(' '*depth + '\\item \\textbf{') 483 out(plaintext_to_latex(doc.canonical_name[-1]) +'}') 484 if doc.summary not in (None, UNKNOWN): 485 out(': %s\n' % self.docstring_to_latex(doc.summary)) 486 if self._crossref: 487 out('\n \\textit{(Section \\ref{%s}' % self.label(doc)) 488 out(', p.~\\pageref{%s})}\n\n' % self.label(doc)) 489 if doc.submodules != UNKNOWN and doc.submodules: 490 out(' '*depth + ' \\begin{itemize}\n') 491 out(' '*depth + '\\setlength{\\parskip}{0ex}\n') 492 for submodule in doc.submodules: 493 self.write_module_tree_item(out, submodule, depth+4) 494 out(' '*depth + ' \\end{itemize}\n')
    495 496 #//////////////////////////////////////////////////////////// 497 #{ Base class trees 498 #//////////////////////////////////////////////////////////// 499
    500 - def base_tree(self, doc, width=None, linespec=None):
    501 if width is None: 502 width = self._find_tree_width(doc)+2 503 linespec = [] 504 s = ('&'*(width-4)+'\\multicolumn{2}{l}{\\textbf{%s}}\n' % 505 plaintext_to_latex('%s'%self._base_name(doc))) 506 s += '\\end{tabular}\n\n' 507 top = 1 508 else: 509 s = self._base_tree_line(doc, width, linespec) 510 top = 0 511 512 if isinstance(doc, ClassDoc): 513 for i in range(len(doc.bases)-1, -1, -1): 514 base = doc.bases[i] 515 spec = (i > 0) 516 s = self.base_tree(base, width, [spec]+linespec) + s 517 518 if top: 519 s = '\\begin{tabular}{%s}\n' % (width*'c') + s 520 521 return s
    522
    523 - def _base_name(self, doc):
    524 if doc.canonical_name is None: 525 if doc.parse_repr is not None: 526 return doc.parse_repr 527 else: 528 return '??' 529 else: 530 return '%s' % doc.canonical_name
    531
    532 - def _find_tree_width(self, doc):
    533 if not isinstance(doc, ClassDoc): return 2 534 width = 2 535 for base in doc.bases: 536 width = max(width, self._find_tree_width(base)+2) 537 return width
    538
    539 - def _base_tree_line(self, doc, width, linespec):
    540 base_name = plaintext_to_latex(self._base_name(doc)) 541 542 # linespec is a list of booleans. 543 s = '%% Line for %s, linespec=%s\n' % (base_name, linespec) 544 545 labelwidth = width-2*len(linespec)-2 546 547 # The base class name. 548 s += ('\\multicolumn{%s}{r}{' % labelwidth) 549 s += '\\settowidth{\\BCL}{%s}' % base_name 550 s += '\\multirow{2}{\\BCL}{%s}}\n' % base_name 551 552 # The vertical bars for other base classes (top half) 553 for vbar in linespec: 554 if vbar: s += '&&\\multicolumn{1}{|c}{}\n' 555 else: s += '&&\n' 556 557 # The horizontal line. 558 s += ' \\\\\\cline{%s-%s}\n' % (labelwidth+1, labelwidth+1) 559 560 # The vertical bar for this base class. 561 s += ' ' + '&'*labelwidth 562 s += '\\multicolumn{1}{c|}{}\n' 563 564 # The vertical bars for other base classes (bottom half) 565 for vbar in linespec: 566 if vbar: s += '&\\multicolumn{1}{|c}{}&\n' 567 else: s += '&&\n' 568 s += ' \\\\\n' 569 570 return s
    571 572 #//////////////////////////////////////////////////////////// 573 #{ Class List 574 #//////////////////////////////////////////////////////////// 575
    576 - def write_class_list(self, out, doc):
    577 groups = [(plaintext_to_latex(group_name), 578 doc.select_variables(group=group_name, imported=False, 579 value_type='class', 580 public=self._public_filter)) 581 for group_name in doc.group_names()] 582 583 # Discard any empty groups; and return if they're all empty. 584 groups = [(g,vars) for (g,vars) in groups if vars] 585 if not groups: return 586 587 # Write a header. 588 self.write_start_of(out, 'Classes') 589 out(self.section('Classes', 1)) 590 out('\\begin{itemize}') 591 out(' \\setlength{\\parskip}{0ex}\n') 592 593 for name, var_docs in groups: 594 if name: 595 out(' \\item \\textbf{%s}\n' % name) 596 out(' \\begin{itemize}\n') 597 # Add the lines for each class 598 for var_doc in var_docs: 599 self.write_class_list_line(out, var_doc) 600 if name: 601 out(' \\end{itemize}\n') 602 603 out('\\end{itemize}\n')
    604
    605 - def write_class_list_line(self, out, var_doc):
    606 if var_doc.value in (None, UNKNOWN): return # shouldn't happen 607 doc = var_doc.value 608 out(' ' + '\\item \\textbf{') 609 out(plaintext_to_latex(var_doc.name) + '}') 610 if doc.summary not in (None, UNKNOWN): 611 out(': %s\n' % self.docstring_to_latex(doc.summary)) 612 if self._crossref: 613 out(('\n \\textit{(Section \\ref{%s}' % self.label(doc))) 614 out((', p.~\\pageref{%s})}\n\n' % self.label(doc)))
    615 616 #//////////////////////////////////////////////////////////// 617 #{ Function List 618 #//////////////////////////////////////////////////////////// 619 _FUNC_GROUP_HEADER = '\n\\large{\\textbf{\\textit{%s}}}\n\n' 620
    621 - def write_func_list(self, out, heading, doc, value_type, seclevel=1):
    622 # Divide all public variables of the given type into groups. 623 groups = [(plaintext_to_latex(group_name), 624 doc.select_variables(group=group_name, imported=False, 625 value_type=value_type, 626 public=self._public_filter)) 627 for group_name in doc.group_names()] 628 629 # Discard any empty groups; and return if they're all empty. 630 groups = [(g,vars) for (g,vars) in groups if vars] 631 if not groups: return 632 633 # Write a header. 634 self.write_start_of(out, heading) 635 out(' '+self.section(heading, seclevel)) 636 637 # Write a section for each group. 638 grouped_inh_vars = {} 639 for name, var_docs in groups: 640 self.write_func_group(out, doc, name, var_docs, grouped_inh_vars) 641 642 # Write a section for each inheritance pseudo-group (used if 643 # inheritance=='grouped') 644 if grouped_inh_vars: 645 for base in doc.mro(): 646 if base in grouped_inh_vars: 647 hdr = ('Inherited from %s' % 648 plaintext_to_latex('%s' % base.canonical_name)) 649 if self._crossref and base in self.class_set: 650 hdr += ('\\textit{(Section \\ref{%s})}' % 651 self.label(base)) 652 out(self._FUNC_GROUP_HEADER % (hdr)) 653 for var_doc in grouped_inh_vars[base]: 654 self.write_func_list_box(out, var_doc)
    655
    656 - def write_func_group(self, out, doc, name, var_docs, grouped_inh_vars):
    657 # Split up the var_docs list, according to the way each var 658 # should be displayed: 659 # - listed_inh_vars -- for listed inherited variables. 660 # - grouped_inh_vars -- for grouped inherited variables. 661 # - normal_vars -- for all other variables. 662 listed_inh_vars = {} 663 normal_vars = [] 664 for var_doc in var_docs: 665 if var_doc.container != doc: 666 base = var_doc.container 667 if (base not in self.class_set or 668 self._inheritance == 'listed'): 669 listed_inh_vars.setdefault(base,[]).append(var_doc) 670 elif self._inheritance == 'grouped': 671 grouped_inh_vars.setdefault(base,[]).append(var_doc) 672 else: 673 normal_vars.append(var_doc) 674 else: 675 normal_vars.append(var_doc) 676 677 # Write a header for the group. 678 if name: 679 out(self._FUNC_GROUP_HEADER % name) 680 # Write an entry for each normal var: 681 for var_doc in normal_vars: 682 self.write_func_list_box(out, var_doc) 683 # Write a subsection for inherited vars: 684 if listed_inh_vars: 685 self.write_func_inheritance_list(out, doc, listed_inh_vars)
    686
    687 - def write_func_inheritance_list(self, out, doc, listed_inh_vars):
    688 for base in doc.mro(): 689 if base not in listed_inh_vars: continue 690 #if str(base.canonical_name) == 'object': continue 691 var_docs = listed_inh_vars[base] 692 if self._public_filter: 693 var_docs = [v for v in var_docs if v.is_public] 694 if var_docs: 695 hdr = ('Inherited from %s' % 696 plaintext_to_latex('%s' % base.canonical_name)) 697 if self._crossref and base in self.class_set: 698 hdr += ('\\textit{(Section \\ref{%s})}' % 699 self.label(base)) 700 out(self._FUNC_GROUP_HEADER % hdr) 701 out('\\begin{quote}\n') 702 out('%s\n' % ', '.join( 703 ['%s()' % plaintext_to_latex(var_doc.name) 704 for var_doc in var_docs])) 705 out('\\end{quote}\n')
    706
    707 - def write_func_list_box(self, out, var_doc):
    708 func_doc = var_doc.value 709 is_inherited = (var_doc.overrides not in (None, UNKNOWN)) 710 711 # nb: this gives the containing section, not a reference 712 # directly to the function. 713 if not is_inherited: 714 out(' \\label{%s}\n' % self.label(func_doc)) 715 out(' %s\n' % self.indexterm(func_doc)) 716 717 # Start box for this function. 718 out(' \\vspace{0.5ex}\n\n') 719 out('\\hspace{.8\\funcindent}') 720 out('\\begin{boxedminipage}{\\funcwidth}\n\n') 721 722 # Function signature. 723 out(' %s\n\n' % self.function_signature(var_doc)) 724 725 if (func_doc.docstring not in (None, UNKNOWN) and 726 func_doc.docstring.strip() != ''): 727 out(' \\vspace{-1.5ex}\n\n') 728 out(' \\rule{\\textwidth}{0.5\\fboxrule}\n') 729 730 # Description 731 out("\\setlength{\\parskip}{2ex}\n") 732 if func_doc.descr not in (None, UNKNOWN): 733 out(self.docstring_to_latex(func_doc.descr, 4)) 734 735 # Parameters 736 out("\\setlength{\\parskip}{1ex}\n") 737 if func_doc.arg_descrs or func_doc.arg_types: 738 # Find the longest name. 739 longest = max([0]+[len(n) for n in func_doc.arg_types]) 740 for names, descrs in func_doc.arg_descrs: 741 longest = max([longest]+[len(n) for n in names]) 742 # Table header. 743 out(' '*6+'\\textbf{Parameters}\n') 744 out(' \\vspace{-1ex}\n\n') 745 out(' '*6+'\\begin{quote}\n') 746 out(' \\begin{Ventry}{%s}\n\n' % (longest*'x')) 747 # Add params that have @type but not @param info: 748 arg_descrs = list(func_doc.arg_descrs) 749 args = set() 750 for arg_names, arg_descr in arg_descrs: 751 args.update(arg_names) 752 for arg in var_doc.value.arg_types: 753 if arg not in args: 754 arg_descrs.append( ([arg],None) ) 755 # Display params 756 for (arg_names, arg_descr) in arg_descrs: 757 arg_name = plaintext_to_latex(', '.join(arg_names)) 758 out('%s\\item[%s]\n\n' % (' '*10, arg_name)) 759 if arg_descr: 760 out(self.docstring_to_latex(arg_descr, 10)) 761 for arg_name in arg_names: 762 arg_typ = func_doc.arg_types.get(arg_name) 763 if arg_typ is not None: 764 if len(arg_names) == 1: 765 lhs = 'type' 766 else: 767 lhs = 'type of %s' % arg_name 768 rhs = self.docstring_to_latex(arg_typ).strip() 769 out('%s{\\it (%s=%s)}\n\n' % (' '*12, lhs, rhs)) 770 out(' \\end{Ventry}\n\n') 771 out(' '*6+'\\end{quote}\n\n') 772 773 # Returns 774 rdescr = func_doc.return_descr 775 rtype = func_doc.return_type 776 if rdescr not in (None, UNKNOWN) or rtype not in (None, UNKNOWN): 777 out(' '*6+'\\textbf{Return Value}\n') 778 out(' \\vspace{-1ex}\n\n') 779 out(' '*6+'\\begin{quote}\n') 780 if rdescr not in (None, UNKNOWN): 781 out(self.docstring_to_latex(rdescr, 6)) 782 if rtype not in (None, UNKNOWN): 783 out(' '*6+'{\\it (type=%s)}\n\n' % 784 self.docstring_to_latex(rtype, 6).strip()) 785 elif rtype not in (None, UNKNOWN): 786 out(self.docstring_to_latex(rtype, 6)) 787 out(' '*6+'\\end{quote}\n\n') 788 789 # Raises 790 if func_doc.exception_descrs not in (None, UNKNOWN, [], ()): 791 out(' '*6+'\\textbf{Raises}\n') 792 out(' \\vspace{-1ex}\n\n') 793 out(' '*6+'\\begin{quote}\n') 794 out(' \\begin{description}\n\n') 795 for name, descr in func_doc.exception_descrs: 796 out(' '*10+'\\item[\\texttt{%s}]\n\n' % 797 plaintext_to_latex('%s' % name)) 798 out(self.docstring_to_latex(descr, 10)) 799 out(' \\end{description}\n\n') 800 out(' '*6+'\\end{quote}\n\n') 801 802 ## Overrides 803 if var_doc.overrides not in (None, UNKNOWN): 804 out(' Overrides: ' + 805 plaintext_to_latex('%s'%var_doc.overrides.canonical_name)) 806 if (func_doc.docstring in (None, UNKNOWN) and 807 var_doc.overrides.value.docstring not in (None, UNKNOWN)): 808 out(' \textit{(inherited documentation)}') 809 out('\n\n') 810 811 # Add version, author, warnings, requirements, notes, etc. 812 self.write_standard_fields(out, func_doc) 813 814 out(' \\end{boxedminipage}\n\n')
    815
    816 - def function_signature(self, var_doc):
    817 func_doc = var_doc.value 818 func_name = var_doc.name 819 820 # This should never happen, but just in case: 821 if func_doc in (None, UNKNOWN): 822 return ('\\raggedright \\textbf{%s}(...)' % 823 plaintext_to_latex(func_name)) 824 825 if func_doc.posargs == UNKNOWN: 826 args = ['...'] 827 else: 828 args = [self.func_arg(name, default) for (name, default) 829 in zip(func_doc.posargs, func_doc.posarg_defaults)] 830 if func_doc.vararg: 831 if func_doc.vararg == '...': 832 args.append('\\textit{...}') 833 else: 834 args.append('*\\textit{%s}' % 835 plaintext_to_latex(func_doc.vararg)) 836 if func_doc.kwarg: 837 args.append('**\\textit{%s}' % 838 plaintext_to_latex(func_doc.kwarg)) 839 return ('\\raggedright \\textbf{%s}(%s)' % 840 (plaintext_to_latex(func_name), ', '.join(args)))
    841
    842 - def func_arg(self, name, default):
    843 s = '\\textit{%s}' % plaintext_to_latex(self._arg_name(name)) 844 if default is not None: 845 s += '={\\tt %s}' % default.summary_pyval_repr().to_latex(None) 846 return s
    847
    848 - def _arg_name(self, arg):
    849 if isinstance(arg, basestring): 850 return arg 851 elif len(arg) == 1: 852 return '(%s,)' % self._arg_name(arg[0]) 853 else: 854 return '(%s)' % (', '.join([self._arg_name(a) for a in arg]))
    855 856 #//////////////////////////////////////////////////////////// 857 #{ Variable List 858 #//////////////////////////////////////////////////////////// 859 _VAR_GROUP_HEADER = '\\multicolumn{2}{|l|}{\\textit{%s}}\\\\\n' 860 861 # Also used for the property list.
    862 - def write_var_list(self, out, heading, doc, value_type, seclevel=1):
    863 groups = [(plaintext_to_latex(group_name), 864 doc.select_variables(group=group_name, imported=False, 865 value_type=value_type, 866 public=self._public_filter)) 867 for group_name in doc.group_names()] 868 869 # Discard any empty groups; and return if they're all empty. 870 groups = [(g,vars) for (g,vars) in groups if vars] 871 if not groups: return 872 873 # Write a header. 874 self.write_start_of(out, heading) 875 out(' '+self.section(heading, seclevel)) 876 877 # [xx] without this, there's a huge gap before the table -- why?? 878 out(' \\vspace{-1cm}\n') 879 880 out('\\hspace{\\varindent}') 881 out('\\begin{longtable}') 882 out('{|p{\\varnamewidth}|') 883 out('p{\\vardescrwidth}|l}\n') 884 out('\\cline{1-2}\n') 885 886 # Set up the headers & footer (this makes the table span 887 # multiple pages in a happy way). 888 out('\\cline{1-2} ') 889 out('\\centering \\textbf{Name} & ') 890 out('\\centering \\textbf{Description}& \\\\\n') 891 out('\\cline{1-2}\n') 892 out('\\endhead') 893 out('\\cline{1-2}') 894 out('\\multicolumn{3}{r}{\\small\\textit{') 895 out('continued on next page}}\\\\') 896 out('\\endfoot') 897 out('\\cline{1-2}\n') 898 out('\\endlastfoot') 899 900 # Write a section for each group. 901 grouped_inh_vars = {} 902 for name, var_docs in groups: 903 self.write_var_group(out, doc, name, var_docs, grouped_inh_vars) 904 905 # Write a section for each inheritance pseudo-group (used if 906 # inheritance=='grouped') 907 if grouped_inh_vars: 908 for base in doc.mro(): 909 if base in grouped_inh_vars: 910 hdr = ('Inherited from %s' % 911 plaintext_to_latex('%s' % base.canonical_name)) 912 if self._crossref and base in self.class_set: 913 hdr += (' \\textit{(Section \\ref{%s})}' % 914 self.label(base)) 915 out(self._VAR_GROUP_HEADER % (hdr)) 916 out('\\cline{1-2}\n') 917 for var_doc in grouped_inh_vars[base]: 918 if isinstance(var_doc.value3, PropertyDoc): 919 self.write_property_list_line(out, var_doc) 920 else: 921 self.write_var_list_line(out, var_doc) 922 923 out('\\end{longtable}\n\n')
    924
    925 - def write_var_group(self, out, doc, name, var_docs, grouped_inh_vars):
    926 # Split up the var_docs list, according to the way each var 927 # should be displayed: 928 # - listed_inh_vars -- for listed inherited variables. 929 # - grouped_inh_vars -- for grouped inherited variables. 930 # - normal_vars -- for all other variables. 931 listed_inh_vars = {} 932 normal_vars = [] 933 for var_doc in var_docs: 934 if var_doc.container != doc: 935 base = var_doc.container 936 if (base not in self.class_set or 937 self._inheritance == 'listed'): 938 listed_inh_vars.setdefault(base,[]).append(var_doc) 939 elif self._inheritance == 'grouped': 940 grouped_inh_vars.setdefault(base,[]).append(var_doc) 941 else: 942 normal_vars.append(var_doc) 943 else: 944 normal_vars.append(var_doc) 945 946 # Write a header for the group. 947 if name: 948 out(self._VAR_GROUP_HEADER % name) 949 out('\\cline{1-2}\n') 950 # Write an entry for each normal var: 951 for var_doc in normal_vars: 952 if isinstance(var_doc.value, PropertyDoc): 953 self.write_property_list_line(out, var_doc) 954 else: 955 self.write_var_list_line(out, var_doc) 956 # Write a subsection for inherited vars: 957 if listed_inh_vars: 958 self.write_var_inheritance_list(out, doc, listed_inh_vars)
    959
    960 - def write_var_inheritance_list(self, out, doc, listed_inh_vars):
    961 for base in doc.mro(): 962 if base not in listed_inh_vars: continue 963 #if str(base.canonical_name) == 'object': continue 964 var_docs = listed_inh_vars[base] 965 if self._public_filter: 966 var_docs = [v for v in var_docs if v.is_public] 967 if var_docs: 968 hdr = ('Inherited from %s' % 969 plaintext_to_latex('%s' % base.canonical_name)) 970 if self._crossref and base in self.class_set: 971 hdr += (' \\textit{(Section \\ref{%s})}' % 972 self.label(base)) 973 out(self._VAR_GROUP_HEADER % hdr) 974 out('\\multicolumn{2}{|p{\\varwidth}|}{' 975 '\\raggedright %s}\\\\\n' % 976 ', '.join(['%s' % plaintext_to_latex(var_doc.name) 977 for var_doc in var_docs])) 978 out('\\cline{1-2}\n')
    979 980
    981 - def write_var_list_line(self, out, var_doc):
    982 out('\\raggedright ') 983 out(plaintext_to_latex(var_doc.name, nbsp=True, breakany=True)) 984 out(' & ') 985 has_descr = var_doc.descr not in (None, UNKNOWN) 986 has_type = var_doc.type_descr not in (None, UNKNOWN) 987 has_value = var_doc.value is not UNKNOWN 988 if has_type or has_value: 989 out('\\raggedright ') 990 if has_descr: 991 out(self.docstring_to_latex(var_doc.descr, 10).strip()) 992 if has_type or has_value: out('\n\n') 993 if has_value: 994 out('\\textbf{Value:} \n{\\tt %s}' % 995 var_doc.value.summary_pyval_repr().to_latex(None)) 996 if has_type: 997 ptype = self.docstring_to_latex(var_doc.type_descr, 12).strip() 998 out('%s{\\it (type=%s)}' % (' '*12, ptype)) 999 out('&\\\\\n') 1000 out('\\cline{1-2}\n')
    1001
    1002 - def write_property_list_line(self, out, var_doc):
    1003 prop_doc = var_doc.value 1004 out('\\raggedright ') 1005 out(plaintext_to_latex(var_doc.name, nbsp=True, breakany=True)) 1006 out(' & ') 1007 has_descr = prop_doc.descr not in (None, UNKNOWN) 1008 has_type = prop_doc.type_descr not in (None, UNKNOWN) 1009 if has_descr or has_type: 1010 out('\\raggedright ') 1011 if has_descr: 1012 out(self.docstring_to_latex(prop_doc.descr, 10).strip()) 1013 if has_type: out('\n\n') 1014 if has_type: 1015 ptype = self.docstring_to_latex(prop_doc.type_descr, 12).strip() 1016 out('%s{\\it (type=%s)}' % (' '*12, ptype)) 1017 # [xx] List the fget/fset/fdel functions? 1018 out('&\\\\\n') 1019 out('\\cline{1-2}\n')
    1020 1021 #//////////////////////////////////////////////////////////// 1022 #{ Standard Fields 1023 #//////////////////////////////////////////////////////////// 1024 1025 # Copied from HTMLWriter:
    1026 - def write_standard_fields(self, out, doc):
    1027 fields = [] 1028 field_values = {} 1029 1030 #if _sort_fields: fields = STANDARD_FIELD_NAMES [XX] 1031 1032 for (field, arg, descr) in doc.metadata: 1033 if field not in field_values: 1034 fields.append(field) 1035 if field.takes_arg: 1036 subfields = field_values.setdefault(field,{}) 1037 subfields.setdefault(arg,[]).append(descr) 1038 else: 1039 field_values.setdefault(field,[]).append(descr) 1040 1041 for field in fields: 1042 if field.takes_arg: 1043 for arg, descrs in field_values[field].items(): 1044 self.write_standard_field(out, doc, field, descrs, arg) 1045 1046 else: 1047 self.write_standard_field(out, doc, field, field_values[field])
    1048
    1049 - def write_standard_field(self, out, doc, field, descrs, arg=''):
    1050 singular = field.singular 1051 plural = field.plural 1052 if arg: 1053 singular += ' (%s)' % arg 1054 plural += ' (%s)' % arg 1055 out(self._descrlist([self.docstring_to_latex(d) for d in descrs], 1056 field.singular, field.plural, field.short))
    1057
    1058 - def _descrlist(self, items, singular, plural=None, short=0):
    1059 if plural is None: plural = singular 1060 if len(items) == 0: return '' 1061 if len(items) == 1 and singular is not None: 1062 return '\\textbf{%s:} %s\n\n' % (singular, items[0]) 1063 if short: 1064 s = '\\textbf{%s:}\n' % plural 1065 items = [item.strip() for item in items] 1066 return s + ',\n '.join(items) + '\n\n' 1067 else: 1068 s = '\\textbf{%s:}\n' % plural 1069 s += '\\begin{quote}\n' 1070 s += ' \\begin{itemize}\n\n \item\n' 1071 s += ' \\setlength{\\parskip}{0.6ex}\n' 1072 s += '\n\n \item '.join(items) 1073 return s + '\n\n\\end{itemize}\n\n\\end{quote}\n\n'
    1074 1075 1076 #//////////////////////////////////////////////////////////// 1077 #{ Docstring -> LaTeX Conversion 1078 #//////////////////////////////////////////////////////////// 1079 1080 # We only need one linker, since we don't use context:
    1081 - class _LatexDocstringLinker(markup.DocstringLinker):
    1082 - def translate_indexterm(self, indexterm):
    1083 indexstr = re.sub(r'["!|@]', r'"\1', indexterm.to_latex(self)) 1084 return ('\\index{%s}\\textit{%s}' % (indexstr, indexstr))
    1085 - def translate_identifier_xref(self, identifier, label=None):
    1086 if label is None: label = markup.plaintext_to_latex(identifier) 1087 return '\\texttt{%s}' % label
    1088 _docstring_linker = _LatexDocstringLinker() 1089
    1090 - def docstring_to_latex(self, docstring, indent=0, breakany=0):
    1091 if docstring is None: return '' 1092 return docstring.to_latex(self._docstring_linker, indent=indent, 1093 hyperref=self._hyperref)
    1094 1095 #//////////////////////////////////////////////////////////// 1096 #{ Helpers 1097 #//////////////////////////////////////////////////////////// 1098
    1099 - def write_header(self, out, where):
    1100 out('%\n% API Documentation') 1101 if self._prj_name: out(' for %s' % self._prj_name) 1102 if isinstance(where, APIDoc): 1103 out('\n%% %s %s' % (self.doc_kind(where), where.canonical_name)) 1104 else: 1105 out('\n%% %s' % where) 1106 out('\n%%\n%% Generated by epydoc %s\n' % epydoc.__version__) 1107 out('%% [%s]\n%%\n' % time.asctime(time.localtime(time.time())))
    1108
    1109 - def write_start_of(self, out, section_name):
    1110 out('\n' + 75*'%' + '\n') 1111 out('%%' + ((71-len(section_name))/2)*' ') 1112 out(section_name) 1113 out(((72-len(section_name))/2)*' ' + '%%\n') 1114 out(75*'%' + '\n\n')
    1115
    1116 - def section(self, title, depth=0):
    1117 sec = self.SECTIONS[depth+self._top_section] 1118 return (('%s\n\n' % sec) % plaintext_to_latex(title))
    1119
    1120 - def sectionstar(self, title, depth):
    1121 sec = self.STARSECTIONS[depth+self._top_section] 1122 return (('%s\n\n' % sec) % plaintext_to_latex(title))
    1123
    1124 - def doc_kind(self, doc):
    1125 if isinstance(doc, ModuleDoc) and doc.is_package == True: 1126 return 'Package' 1127 elif (isinstance(doc, ModuleDoc) and 1128 doc.canonical_name[0].startswith('script')): 1129 return 'Script' 1130 elif isinstance(doc, ModuleDoc): 1131 return 'Module' 1132 elif isinstance(doc, ClassDoc): 1133 return 'Class' 1134 elif isinstance(doc, ClassMethodDoc): 1135 return 'Class Method' 1136 elif isinstance(doc, StaticMethodDoc): 1137 return 'Static Method' 1138 elif isinstance(doc, RoutineDoc): 1139 if isinstance(self.docindex.container(doc), ClassDoc): 1140 return 'Method' 1141 else: 1142 return 'Function' 1143 else: 1144 return 'Variable'
    1145
    1146 - def indexterm(self, doc, pos='only'):
    1147 """Mark a term or section for inclusion in the index.""" 1148 if not self._index: return '' 1149 if isinstance(doc, RoutineDoc) and not self._index_functions: 1150 return '' 1151 1152 pieces = [] 1153 while doc is not None: 1154 if doc.canonical_name == UNKNOWN: 1155 return '' # Give up. 1156 pieces.append('%s \\textit{(%s)}' % 1157 (plaintext_to_latex('%s'%doc.canonical_name), 1158 self.doc_kind(doc).lower())) 1159 doc = self.docindex.container(doc) 1160 if doc == UNKNOWN: 1161 return '' # Give up. 1162 1163 pieces.reverse() 1164 if pos == 'only': 1165 return '\\index{%s}\n' % '!'.join(pieces) 1166 elif pos == 'start': 1167 return '\\index{%s|(}\n' % '!'.join(pieces) 1168 elif pos == 'end': 1169 return '\\index{%s|)}\n' % '!'.join(pieces) 1170 else: 1171 raise AssertionError('Bad index position %s' % pos)
    1172
    1173 - def label(self, doc):
    1174 return ':'.join(doc.canonical_name)
    1175 1176 #: Map the Python encoding representation into mismatching LaTeX ones. 1177 latex_encodings = { 1178 'utf-8': 'utf8', 1179 } 1180
    1181 - def get_latex_encoding(self):
    1182 """ 1183 @return: The LaTeX representation of the selected encoding. 1184 @rtype: C{str} 1185 """ 1186 enc = self._encoding.lower() 1187 return self.latex_encodings.get(enc, enc)
    1188

    epydoc-3.0.1+dfsg/doc/api/epydoc-log.html0000644000175000017500000001741110750103050020436 0ustar pronovicpronovic Epydoc Log

    Epydoc Log

    Epydoc started at Wed Jan 30 14:03:35 2008

    Warning: epydoc.docwriter.dotgraph.DotGraphUmlClassNode._summary in multiple groups
    Docstring Warning:
    Failed identifier crossreference targets:
    - _val_is_private
          (from epydoc.docwriter.html.HTMLWriter._private_subclasses)
    - docutils.nodes.Node.walk()
          (from epydoc.markup.restructuredtext._DocumentPseudoWriter.translate)
    - docutils.nodes.Node.walkabout()
          (from epydoc.markup.restructuredtext._DocumentPseudoWriter.translate)
    - docutils.nodes.NodeVisitor
          (from epydoc.markup.restructuredtext._DocumentPseudoWriter.translate)
    - docutils.nodes.node_class_names
          (from epydoc.markup.restructuredtext._DocumentPseudoWriter.translate)
    

    Epydoc Options

    css = 'white'
    debug = True
    docformat = 'plaintext'
    graphs = ('classtree', 'callgraph', 'umlclasstree')
    include_log = True
    names = ['src/epydoc/']
    prj_link = 'epydoc 3.0.1'
    prj_name = 'epydoc'
    prj_url = 'http://epydoc.sourceforge.net'
    target = 'html/api'
    verbose = 1
    verbosity = 1
    action = 'html'
    configfiles = None
    dotpath = None
    exclude = []
    exclude_introspect = []
    exclude_parse = []
    external_api = []
    external_api_file = []
    external_api_root = []
    fail_on = None
    graph_font = None
    graph_font_size = None
    help_file = None
    include_source_code = True
    inheritance = 'listed'
    introspect = True
    list_classes_separately = False
    load_pickle = False
    parse = True
    profile = False
    pstat_files = ['profile.out']
    quiet = 0
    redundant_details = False
    show_frames = True
    show_imports = False
    show_private = True
    simple_term = False
    src_code_tab_width = 8
    top_page = None

    Epydoc finished at Wed Jan 30 14:10:01 2008

    (Elapsed time: 6 minutes, 26 seconds)

    epydoc-3.0.1+dfsg/doc/api/epydoc-module.html0000644000175000017500000007305510750103050021150 0ustar pronovicpronovic epydoc
    Package epydoc
    [hide private]
    [frames] | no frames]

    Package epydoc

    source code

    Automatic Python reference documentation generator. Epydoc processes Python modules and docstrings to generate formatted API documentation, in the form of HTML pages. Epydoc can be used via a command-line interface (epydoc.cli) and a graphical interface (epydoc.gui). Both interfaces let the user specify a set of modules or other objects to document, and produce API documentation using the following steps:

    1. Extract basic information about the specified objects, and objects that are related to them (such as the values defined by a module). This can be done via introspection, parsing, or both:
      • Introspection imports the objects, and examines them directly using Python's introspection mechanisms.
      • Parsing reads the Python source files that define the objects, and extracts information from those files.
    2. Combine and process that information.
      • Merging: Merge the information obtained from introspection & parsing each object into a single structure.
      • Linking: Replace any "pointers" that were created for imported variables with the documentation that they point to.
      • Naming: Assign unique canonical names to each of the specified objects, and any related objects.
      • Docstrings: Parse the docstrings of each of the specified objects.
      • Inheritance: Add variables to classes for any values that they inherit from their base classes.
    3. Generate output. Output can be generated in a variety of formats:
      • An HTML webpage.
      • A LaTeX document (which can be rendered as a PDF file)
      • A plaintext description.
    Overview of epydoc's architecture
    Overview of epydoc's architecture -- The boxes represent steps in epydoc's processing chain. Arrows are annotated with the data classes used to communicate between steps. The lines along the right side mark what portions of the processing chain are initiated by build_doc_index() and cli(). Click on any item to see its documentation.

    Package Organization

    The epydoc package contains the following subpackages and modules:

    Package Tree for epydoc
    Package Tree for epydoc

    The user interfaces are provided by the gui and cli modules. The apidoc module defines the basic data types used to record information about Python objects. The programmatic interface to epydoc is provided by docbuilder. Docstring markup parsing is handled by the markup package, and output generation is handled by the docwriter package. See the submodule list for more information about the submodules and subpackages.


    Author: Edward Loper

    Requires: Python 2.3+

    Version: 3.0.1

    See Also:
    The epydoc webpage, The epytext markup language manual
    To Do:
    • Create a better default top_page than trees.html.
    • Fix trees.html to work when documenting non-top-level modules/packages
    • Implement @include
    • Optimize epytext
    • More doctests
    • When introspecting, limit how much introspection you do (eg, don't construct docs for imported modules' vars if it's not necessary)

    Bug: UserDict.* is interpreted as imported .. why??

    License: IBM Open Source License

    Copyright: © 2006 Edward Loper

    Contributors (Alphabetical Order):
    Submodules [hide private]
        User Interface
        Basic Data Types
    • epydoc.apidoc: Classes for encoding API documentation about Python programs.
        Documentation Generation
    • epydoc.docbuilder: Construct data structures that encode the API documentation for Python objects.
    • epydoc.docintrospecter: Extract API documentation about python objects by directly introspecting their values.
    • epydoc.docparser: Extract API documentation about python objects by parsing their source code.
        Docstring Processing
        Output Generation
        Completeness Checking
        Miscellaneous
    • epydoc.compat: Backwards compatibility with previous versions of Python.
    • epydoc.log: Functions used to report messages and progress updates to the user.
    • epydoc.test: Regression testing.
    • epydoc.util: Miscellaneous utility functions that are used by multiple modules.

    Variables [hide private]
      DEBUG = True
    True if debugging is turned on.
      __author__ = 'Edward Loper <edloper@gradient.cis.upenn.edu>'
    The primary author of eypdoc
      __license__ = 'IBM Open Source License'
    The license governing the use and distribution of epydoc
      __url__ = 'http://epydoc.sourceforge.net'
    The URL for epydoc's homepage
      __version__ = '3.0.1'
    The version of epydoc
    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_css-module.html0000644000175000017500000007636710750103050024775 0ustar pronovicpronovic epydoc.docwriter.html_css
    Package epydoc :: Package docwriter :: Module html_css
    [hide private]
    [frames] | no frames]

    Module html_css

    source code

    Predefined CSS stylesheets for the HTML outputter (epydoc.docwriter.html).

    Functions [hide private]
     
    _set_colors(template, *dicts) source code
    string
    _rv(match)
    Given a regexp match for a color, return the reverse-video version of that color.
    source code
     
    _darken_darks(match) source code
    Variables [hide private]
      TEMPLATE = '\n\n/* Epydoc CSS Stylesheet\n *\n * This styleshe...
      _COLOR_RE = re.compile(r'#(..)(..)(..)')
      _WHITE_COLORS = {'body_bg': '#ffffff', 'body_fg': '#000000', '...
      _BLUE_COLORS = {'body_bg': '#000070', 'body_fg': '#ffffff', 'b...
      _WHITE = '\n\n/* Epydoc CSS Stylesheet\n *\n * This stylesheet...
      _BLUE = '\n\n/* Epydoc CSS Stylesheet\n *\n * This stylesheet ...
      _GREEN = '\n\n/* Epydoc CSS Stylesheet\n *\n * This stylesheet...
      _BLACK = '\n\n/* Epydoc CSS Stylesheet\n *\n * This stylesheet...
      _GRAYSCALE = '\n\n/* Epydoc CSS Stylesheet\n *\n * This styles...
    dictionary from string to (string, string) STYLESHEETS = {'black': ('\n\n/* Epydoc CSS Stylesheet\n *\n *...
    A dictionary mapping from stylesheet names to CSS stylesheets and descriptions.
    Function Details [hide private]

    _rv(match)

    source code 

    Given a regexp match for a color, return the reverse-video version of that color.

    Parameters:
    • match (Match) - A regular expression match.
    Returns: string
    The reverse-video color.

    Variables Details [hide private]

    TEMPLATE

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    _WHITE_COLORS

    Value:
    {'body_bg': '#ffffff',
     'body_fg': '#000000',
     'body_link': '#0000ff',
     'body_visited_link': '#204080',
     'doctest_bg': '#e8f0f8',
     'doctest_border': '1px solid #708890',
     'doctest_fg': '#000000',
     'doctest_in_table_bg': '#dce4ec',
    ...
    

    _BLUE_COLORS

    Value:
    {'body_bg': '#000070',
     'body_fg': '#ffffff',
     'body_link': '#ffffff',
     'body_visited_link': '#d0d0ff',
     'doctest_bg': '#c0e0f8',
     'doctest_border': '1px solid #708890',
     'doctest_fg': '#000000',
     'doctest_in_table_bg': '#c0e0f8',
    ...
    

    _WHITE

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    _BLUE

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    _GREEN

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    _BLACK

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    _GRAYSCALE

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    STYLESHEETS

    A dictionary mapping from stylesheet names to CSS stylesheets and descriptions. A single stylesheet may have multiple names. Currently, the following stylesheets are defined:
    • default: The default stylesheet (synonym for white).
    • white: Black on white, with blue highlights (similar to javadoc).
    • blue: Black on steel blue.
    • green: Black on green.
    • black: White on black, with blue highlights
    • grayscale: Grayscale black on white.
    • none: An empty stylesheet.
    Type:
    dictionary from string to (string, string)
    Value:
    {'black': ('''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._EpydocReader-class.html0000644000175000017500000006504310750103050030427 0ustar pronovicpronovic epydoc.markup.restructuredtext._EpydocReader
    Package epydoc :: Package markup :: Module restructuredtext :: Class _EpydocReader
    [hide private]
    [frames] | no frames]

    Class _EpydocReader

    source code


    A reader that captures all errors that are generated by parsing, and appends them to a list.

    Instance Methods [hide private]
     
    get_transforms(self)
    Transforms required by this class.
    source code
    call graph 
     
    __init__(self, errors)
    Initialize the Reader instance.
    source code
    call graph 
     
    new_document(self)
    Create and return a new empty document tree (root node).
    source code
    call graph 
     
    report(self, error) source code

    Inherited from docwriter.xlink.ApiLinkReader: read

    Inherited from docutils.readers.Reader: parse, set_parser

    Inherited from docutils.Component: supports

    Class Methods [hide private]

    Inherited from docwriter.xlink.ApiLinkReader: read_configuration

    Class Variables [hide private]
      default_transforms = list(ApiLinkReader.default_transforms)
      v = '5'

    Inherited from docwriter.xlink.ApiLinkReader: settings_spec

    Inherited from docwriter.xlink.ApiLinkReader (private): _conf

    Inherited from docutils.readers.standalone.Reader: config_section, config_section_dependencies, document, supported

    Inherited from docutils.readers.Reader: component_type

    Inherited from docutils.SettingsSpec: relative_path_settings, settings_default_overrides, settings_defaults

    Inherited from docutils.TransformSpec: unknown_reference_resolvers

    Method Details [hide private]

    get_transforms(self)

    source code 
    call graph 
    Transforms required by this class. Override in subclasses.
    Overrides: docutils.TransformSpec.get_transforms
    (inherited documentation)

    __init__(self, errors)
    (Constructor)

    source code 
    call graph 

    Initialize the Reader instance.

    Several instance attributes are defined with dummy initial values. Subclasses may use these attributes as they wish.

    Overrides: docutils.readers.Reader.__init__
    (inherited documentation)

    new_document(self)

    source code 
    call graph 
    Create and return a new empty document tree (root node).
    Overrides: docutils.readers.Reader.new_document
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph.DotGraphEdge-class.html0000644000175000017500000004023710750103050027070 0ustar pronovicpronovic epydoc.docwriter.dotgraph.DotGraphEdge
    Package epydoc :: Package docwriter :: Module dotgraph :: Class DotGraphEdge
    [hide private]
    [frames] | no frames]

    Class DotGraphEdge

    source code

    Instance Methods [hide private]
     
    __init__(self, start, end, label=None, **attribs) source code
    call graph 
     
    __getitem__(self, attr) source code
     
    __setitem__(self, attr, val) source code
    call graph 
     
    to_dotfile(self)
    Return the dot commands that should be used to render this edge.
    source code
    call graph 
    Instance Variables [hide private]
    DotGraphNode start
    DotGraphNode end
    Method Details [hide private]

    __init__(self, start, end, label=None, **attribs)
    (Constructor)

    source code 
    call graph 
    Parameters:

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.StaticMethodDoc-class.html0000644000175000017500000007074610750103050025247 0ustar pronovicpronovic epydoc.apidoc.StaticMethodDoc
    Package epydoc :: Module apidoc :: Class StaticMethodDoc
    [hide private]
    [frames] | no frames]

    Class StaticMethodDoc

    source code


    Instance Methods [hide private]

    Inherited from RoutineDoc: all_args, is_detailed

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__, apidoc_links

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from RoutineDoc: callgraph_uid

    Inherited from ValueDoc: canonical_name, toktree

        Signature

    Inherited from RoutineDoc: kwarg, lineno, posarg_defaults, posargs, vararg

        Decorators

    Inherited from RoutineDoc: decorators

        Information Extracted from Docstrings

    Inherited from RoutineDoc: arg_descrs, arg_types, exception_descrs, return_descr, return_type

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.xlink-module.html0000644000175000017500000000416410750103050025053 0ustar pronovicpronovic xlink

    Module xlink


    Classes

    ApiLinkReader
    DocUrlGenerator
    UrlGenerator
    VoidUrlGenerator

    Functions

    create_api_role
    register_api
    set_api_file
    set_api_root
    split_name

    Variables

    api_register

    [hide private] epydoc-3.0.1+dfsg/doc/api/todo-index.html0000644000175000017500000002221610750103050020445 0ustar pronovicpronovic To Do List
     
    [hide private]
    [frames] | no frames]
    [ Identifiers | Term Definitions | Bugs | To Do ]

    To Do List



    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr._ColorizerState-class.html0000644000175000017500000002674010750103050027556 0ustar pronovicpronovic epydoc.markup.pyval_repr._ColorizerState
    Package epydoc :: Package markup :: Module pyval_repr :: Class _ColorizerState
    [hide private]
    [frames] | no frames]

    Class _ColorizerState

    source code

    An object uesd to keep track of the current state of the pyval colorizer. The mark()/restore() methods can be used to set a backup point, and restore back to that backup point. This is used by several colorization methods that first try colorizing their object on a single line (setting linebreakok=False); and then fall back on a multi-line output if that fails. The score variable is used to keep track of a 'score', reflecting how good we think this repr is. E.g., unhelpful values like '<Foo instance at 0x12345>' get low scores. If the score is too low, we'll use the parse-derived repr instead.

    Instance Methods [hide private]
     
    __init__(self) source code
    call graph 
     
    mark(self) source code
    call graph 
     
    restore(self, mark) source code
    call graph 
    Instance Variables [hide private]
      score
    How good this represention is?
    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph.DotGraph-class.html0000644000175000017500000011566210750103050026310 0ustar pronovicpronovic epydoc.docwriter.dotgraph.DotGraph
    Package epydoc :: Package docwriter :: Module dotgraph :: Class DotGraph
    [hide private]
    [frames] | no frames]

    Class DotGraph

    source code

    A dot directed graph. The contents of the graph are constructed from the following instance variables:

    • nodes: A list of DotGraphNodes, encoding the nodes that are present in the graph. Each node is characterized a set of attributes, including an optional label.
    • edges: A list of DotGraphEdges, encoding the edges that are present in the graph. Each edge is characterized by a set of attributes, including an optional label.
    • node_defaults: Default attributes for nodes.
    • edge_defaults: Default attributes for edges.
    • body: A string that is appended as-is in the body of the graph. This can be used to build more complex dot graphs.

    The link() method can be used to resolve crossreference links within the graph. In particular, if the 'href' attribute of any node or edge is assigned a value of the form <name>, then it will be replaced by the URL of the object with that name. This applies to the body as well as the nodes and edges.

    To render the graph, use the methods write() and render(). Usually, you should call link() before you render the graph.

    Instance Methods [hide private]
     
    __init__(self, title, body='', node_defaults=None, edge_defaults=None, caption=None)
    Create a new DotGraph.
    source code
    call graph 
     
    to_html(self, image_file, image_url, center=True)
    Return the HTML code that should be uesd to display this graph (including a client-side image map).
    source code
    call graph 
     
    link(self, docstring_linker)
    Replace any href attributes whose value is <name> with the url of the object whose name is <name>.
    source code
    call graph 
     
    _link_href(self, attribs, docstring_linker)
    Helper for link()
    source code
    call graph 
     
    write(self, filename, language='gif')
    Render the graph using the output format language, and write the result to filename.
    source code
     
    render(self, language='gif')
    Use the dot command to render this graph, using the output format language.
    source code
     
    _run_dot(self, *options) source code
    call graph 
     
    to_dotfile(self)
    Return the string contents of the dot file that should be used to render this graph.
    source code
    call graph 
    Class Variables [hide private]
      _uids = set(['call_graph_for___add__', 'call_graph_for___cmp__...
    A set of all uids that that have been generated, used to ensure that each new graph has a unique uid.
      DEFAULT_NODE_DEFAULTS = {'fontname': 'Helvetica', 'fontsize': 10}
      DEFAULT_EDGE_DEFAULTS = {'fontname': 'Helvetica', 'fontsize': 10}
    Instance Variables [hide private]
      title
    The title of the graph.
      caption
    A caption for the graph.
    list of DotGraphNode nodes
    A list of the nodes that are present in the graph.
    list of DotGraphEdge edges
    A list of the edges that are present in the graph.
    str body
    A string that should be included as-is in the body of the graph.
      node_defaults
    Default attribute values for nodes.
      edge_defaults
    Default attribute values for edges.
      uid
    A unique identifier for this graph.
    Method Details [hide private]

    to_html(self, image_file, image_url, center=True)

    source code 
    call graph 
    Return the HTML code that should be uesd to display this graph (including a client-side image map).
    Parameters:
    • image_url - The URL of the image file for this graph; this should be generated separately with the write() method.

    write(self, filename, language='gif')

    source code 
    Render the graph using the output format language, and write the result to filename.
    Returns:
    True if rendering was successful.

    render(self, language='gif')

    source code 
    Use the dot command to render this graph, using the output format language. Return the result as a string, or None if the rendering failed.

    Class Variable Details [hide private]

    _uids

    A set of all uids that that have been generated, used to ensure that each new graph has a unique uid.
    Value:
    set(['call_graph_for___add__',
         'call_graph_for___cmp__',
         'call_graph_for___cmp___2',
         'call_graph_for___cmp___3',
         'call_graph_for___getitem__',
         'call_graph_for___getstate__',
         'call_graph_for___hash__',
         'call_graph_for___hash___2',
    ...
    

    Instance Variable Details [hide private]

    uid

    A unique identifier for this graph. This can be used as a filename when rendering the graph. No two DotGraphs will have the same uid.

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_colorize-module.html0000644000175000017500000003223710750103050026017 0ustar pronovicpronovic epydoc.docwriter.html_colorize
    Package epydoc :: Package docwriter :: Module html_colorize
    [hide private]
    [frames] | no frames]

    Module html_colorize

    source code

    Functions to produce colorized HTML code for various objects. Currently, html_colorize defines functions to colorize Python source code.

    Classes [hide private]
      PythonSourceColorizer
    A class that renders a python module's source code into HTML pages.
    Variables [hide private]
      PYSRC_JAVASCRIPTS = 'function expand(id) {\n var elt = docume...
    Javascript code for the PythonSourceColorizer
      PYSRC_EXPANDTO_JAVASCRIPT = '<script type="text/javascript">\n...
      _HDR = '<?xml version="1.0" encoding="ascii"?>\n <!DOCT...
      _FOOT = '</body></html>'
    Variables Details [hide private]

    PYSRC_JAVASCRIPTS

    Javascript code for the PythonSourceColorizer

    Value:
    '''function expand(id) {
      var elt = document.getElementById(id+"-expanded");
      if (elt) elt.style.display = "block";
      var elt = document.getElementById(id+"-expanded-linenums");
      if (elt) elt.style.display = "block";
      var elt = document.getElementById(id+"-collapsed");
      if (elt) { elt.innerHTML = ""; elt.style.display = "none"; }
      var elt = document.getElementById(id+"-collapsed-linenums");
    ...
    

    PYSRC_EXPANDTO_JAVASCRIPT

    Value:
    '''<script type="text/javascript">
    <!--
    expandto(location.href);
    // -->
    </script>
    '''
    

    _HDR

    Value:
    '''<?xml version="1.0" encoding="ascii"?>
            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "DTD/xhtml1-transitional.dtd">
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang=\
    "en">
            <head>
              <title>$title$</title>
              <link rel="stylesheet" href="epydoc.css" type="text/css" />
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.gui.EpydocGUI-class.html0000644000175000017500000006172010750103050023336 0ustar pronovicpronovic epydoc.gui.EpydocGUI
    Package epydoc :: Module gui :: Class EpydocGUI
    [hide private]
    [frames] | no frames]

    Class EpydocGUI

    source code

    A graphical user interace to epydoc.

    Instance Methods [hide private]
     
    __init__(self) source code
     
    _init_menubar(self) source code
     
    _init_module_list(self, mainframe) source code
     
    _init_progress_bar(self, mainframe) source code
     
    _init_messages(self, msgsframe, ctrlframe) source code
     
    _update_msg_tags(self, *e) source code
     
    _init_options(self, optsframe, ctrlframe) source code
     
    _init_bindings(self) source code
     
    _options_toggle(self, *e) source code
     
    _messages_toggle(self, *e) source code
     
    _configure(self, event) source code
     
    _delete_module(self, *e) source code
     
    _entry_module(self, *e) source code
     
    _browse_module(self, *e) source code
     
    _browse_css(self, *e) source code
     
    _browse_help(self, *e) source code
     
    _browse_out(self, *e) source code
     
    destroy(self, *e) source code
     
    add_module(self, name, check=0) source code
     
    mainloop(self, *args, **kwargs) source code
     
    _getopts(self) source code
     
    _go(self, *e) source code
     
    _update_messages(self) source code
     
    _update(self, dt, id) source code
     
    _new(self, *e) source code
     
    _open(self, *e) source code
     
    open(self, prjfile) source code
     
    _save(self, *e) source code
     
    _saveas(self, *e) source code
    epydoc-3.0.1+dfsg/doc/api/class-tree.html0000644000175000017500000007071610750103050020445 0ustar pronovicpronovic Class Hierarchy
     
    [hide private]
    [frames] | no frames]
    [ Module Hierarchy | Class Hierarchy ]

    Class Hierarchy

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext.OptimizedReporter-class.html0000644000175000017500000004211110750103050031400 0ustar pronovicpronovic epydoc.markup.restructuredtext.OptimizedReporter
    Package epydoc :: Package markup :: Module restructuredtext :: Class OptimizedReporter
    [hide private]
    [frames] | no frames]

    Class OptimizedReporter

    source code


    A reporter that ignores all debug messages. This is used to shave a couple seconds off of epydoc's run time, since docutils isn't very fast about processing its own debug messages.

    Instance Methods [hide private]
     
    debug(self, *args, **kwargs)
    Level-0, "DEBUG": an internal reporting issue.
    source code
    call graph 

    Inherited from docutils.utils.Reporter: __init__, attach_observer, detach_observer, error, info, notify_observers, set_conditions, severe, system_message, warning

    Class Variables [hide private]

    Inherited from docutils.utils.Reporter: DEBUG_LEVEL, ERROR_LEVEL, INFO_LEVEL, SEVERE_LEVEL, WARNING_LEVEL, levels

    Instance Variables [hide private]

    Inherited from docutils.utils.Reporter: debug_flag, encoding, error_handler, halt_level, max_level, observers, report_level, source, stream

    Method Details [hide private]

    debug(self, *args, **kwargs)

    source code 
    call graph 
    Level-0, "DEBUG": an internal reporting issue. Typically, there is no effect on the processing. Level-0 system messages are handled separately from the others.
    Overrides: docutils.utils.Reporter.debug
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._EpydocLaTeXTranslator-class.html0000644000175000017500000007421410750103050032254 0ustar pronovicpronovic epydoc.markup.restructuredtext._EpydocLaTeXTranslator
    Package epydoc :: Package markup :: Module restructuredtext :: Class _EpydocLaTeXTranslator
    [hide private]
    [frames] | no frames]

    Class _EpydocLaTeXTranslator

    source code


    Instance Methods [hide private]
     
    __init__(self, document, docstring_linker) source code
     
    visit_title_reference(self, node) source code
     
    visit_document(self, node) source code
     
    depart_document(self, node) source code
     
    visit_dotgraph(self, node) source code
     
    visit_doctest_block(self, node) source code

    Inherited from docutils.writers.latex2e.LaTeXTranslator: astext, attval, bookmark, depart_Text, depart_address, depart_admonition, depart_attention, depart_attribution, depart_author, depart_authors, depart_block_quote, depart_bullet_list, depart_caption, depart_caution, depart_citation, depart_citation_reference, depart_classifier, depart_colspec, depart_compound, depart_contact, depart_container, depart_copyright, depart_danger, depart_date, depart_decoration, depart_definition, depart_definition_list, depart_definition_list_item, depart_description, depart_docinfo, depart_docinfo_item, depart_doctest_block, depart_emphasis, depart_entry, depart_enumerated_list, depart_error, depart_field, depart_field_argument, depart_field_body, depart_field_list, depart_field_name, depart_figure, depart_footer, depart_footnote, depart_footnote_reference, depart_generated, depart_header, depart_hint, depart_image, depart_important, depart_inline, depart_interpreted, depart_label, depart_legend, depart_line, depart_line_block, depart_list_item, depart_literal, depart_literal_block, depart_meta, depart_note, depart_option, depart_option_argument, depart_option_group, depart_option_list, depart_option_list_item, depart_option_string, depart_organization, depart_paragraph, depart_problematic, depart_reference, depart_revision, depart_row, depart_rubric, depart_section, depart_sidebar, depart_status, depart_strong, depart_subscript, depart_subtitle, depart_superscript, depart_system_message, depart_table, depart_target, depart_tbody, depart_term, depart_tgroup, depart_thead, depart_tip, depart_title, depart_title_reference, depart_topic, depart_transition, depart_version, depart_warning, encode, ensure_math, label_delim, language_label, latex_image_length, to_latex_encoding, unicode_to_latex, unimplemented_visit, visit_Text, visit_address, visit_admonition, visit_attention, visit_attribution, visit_author, visit_authors, visit_block_quote, visit_bullet_list, visit_caption, visit_caution, visit_citation, visit_citation_reference, visit_classifier, visit_colspec, visit_comment, visit_compound, visit_contact, visit_container, visit_copyright, visit_danger, visit_date, visit_decoration, visit_definition, visit_definition_list, visit_definition_list_item, visit_description, visit_docinfo, visit_docinfo_item, visit_emphasis, visit_entry, visit_enumerated_list, visit_error, visit_field, visit_field_argument, visit_field_body, visit_field_list, visit_field_name, visit_figure, visit_footer, visit_footnote, visit_footnote_reference, visit_generated, visit_header, visit_hint, visit_image, visit_important, visit_inline, visit_interpreted, visit_label, visit_legend, visit_line, visit_line_block, visit_list_item, visit_literal, visit_literal_block, visit_meta, visit_note, visit_option, visit_option_argument, visit_option_group, visit_option_list, visit_option_list_item, visit_option_string, visit_organization, visit_paragraph, visit_problematic, visit_raw, visit_reference, visit_revision, visit_row, visit_rubric, visit_section, visit_sidebar, visit_status, visit_strong, visit_subscript, visit_substitution_definition, visit_substitution_reference, visit_subtitle, visit_superscript, visit_system_message, visit_table, visit_target, visit_tbody, visit_term, visit_tgroup, visit_thead, visit_tip, visit_title, visit_topic, visit_transition, visit_version, visit_warning

    Inherited from docutils.nodes.NodeVisitor: dispatch_departure, dispatch_visit, unknown_departure, unknown_visit

    Class Variables [hide private]
      settings = None

    Inherited from docutils.writers.latex2e.LaTeXTranslator: attribution_formats, compound_enumerators, generator, hyperlink_color, latex_equivalents, latex_head, linking, section_enumerator_separator, section_prefix_for_enumerators, stylesheet, use_latex_toc, use_optionlist_for_docinfo

    Inherited from docutils.nodes.NodeVisitor: optional

    Method Details [hide private]

    __init__(self, document, docstring_linker)
    (Constructor)

    source code 
    Overrides: docutils.nodes.NodeVisitor.__init__

    visit_title_reference(self, node)

    source code 
    Overrides: docutils.writers.latex2e.LaTeXTranslator.visit_title_reference

    visit_document(self, node)

    source code 
    Overrides: docutils.writers.latex2e.LaTeXTranslator.visit_document

    depart_document(self, node)

    source code 
    Overrides: docutils.writers.latex2e.LaTeXTranslator.depart_document

    visit_doctest_block(self, node)

    source code 
    Overrides: docutils.writers.latex2e.LaTeXTranslator.visit_doctest_block

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.plaintext-pysrc.html0000644000175000017500000036047510750103050025040 0ustar pronovicpronovic epydoc.docwriter.plaintext
    Package epydoc :: Package docwriter :: Module plaintext
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.plaintext

      1  # epydoc -- Plaintext output generation 
      2  # 
      3  # Copyright (C) 2005 Edward Loper 
      4  # Author: Edward Loper <edloper@loper.org> 
      5  # URL: <http://epydoc.sf.net> 
      6  # 
      7  # $Id: plaintext.py 1473 2007-02-13 19:46:05Z edloper $ 
      8   
      9  """ 
     10  Plaintext output generation. 
     11  """ 
     12  __docformat__ = 'epytext en' 
     13   
     14  from epydoc.apidoc import * 
     15  import re 
     16   
    
    17 -class PlaintextWriter:
    18 - def write(self, api_doc, **options):
    19 result = [] 20 out = result.append 21 22 self._cols = options.get('cols', 75) 23 24 try: 25 if isinstance(api_doc, ModuleDoc): 26 self.write_module(out, api_doc) 27 elif isinstance(api_doc, ClassDoc): 28 self.write_class(out, api_doc) 29 elif isinstance(api_doc, RoutineDoc): 30 self.write_function(out, api_doc) 31 else: 32 assert 0, ('%s not handled yet' % api_doc.__class__) 33 except Exception, e: 34 print '\n\n' 35 print ''.join(result) 36 raise 37 38 return ''.join(result)
    39
    40 - def write_module(self, out, mod_doc):
    41 #for n,v in mod_doc.variables.items(): 42 # print n, `v.value`, `v.value.value` 43 44 # The cannonical name of the module. 45 out(self.section('Module Name')) 46 out(' %s\n\n' % mod_doc.canonical_name) 47 48 # The module's description. 49 if mod_doc.descr not in (None, '', UNKNOWN): 50 out(self.section('Description')) 51 out(mod_doc.descr.to_plaintext(None, indent=4)) 52 53 #out('metadata: %s\n\n' % mod_doc.metadata) # [xx] testing 54 55 self.write_list(out, 'Classes', mod_doc, value_type='class') 56 self.write_list(out, 'Functions', mod_doc, value_type='function') 57 self.write_list(out, 'Variables', mod_doc, value_type='other')
    58 # hmm.. do this as just a flat list?? 59 #self.write_list(out, 'Imports', mod_doc, imported=True, verbose=False) 60
    61 - def baselist(self, class_doc):
    62 if class_doc.bases is UNKNOWN: 63 return '(unknown bases)' 64 if len(class_doc.bases) == 0: return '' 65 s = '(' 66 class_parent = class_doc.canonical_name.container() 67 for i, base in enumerate(class_doc.bases): 68 if base.canonical_name is None: 69 if base.parse_repr is not UNKNOWN: 70 s += base.parse_repr 71 else: 72 s += '??' 73 elif base.canonical_name.container() == class_parent: 74 s += str(base.canonical_name[-1]) 75 else: 76 s += str(base.canonical_name) 77 if i < len(class_doc.bases)-1: out(', ') 78 return s+')'
    79
    80 - def write_class(self, out, class_doc, name=None, prefix='', verbose=True):
    81 baselist = self.baselist(class_doc) 82 83 # If we're at the top level, then list the cannonical name of 84 # the class; otherwise, our parent will have already printed 85 # the name of the variable containing the class. 86 if prefix == '': 87 out(self.section('Class Name')) 88 out(' %s%s\n\n' % (class_doc.canonical_name, baselist)) 89 else: 90 out(prefix + 'class %s' % self.bold(str(name)) + baselist+'\n') 91 92 if not verbose: return 93 94 # Indent the body 95 if prefix != '': 96 prefix += ' | ' 97 98 # The class's description. 99 if class_doc.descr not in (None, '', UNKNOWN): 100 if prefix == '': 101 out(self.section('Description', prefix)) 102 out(self._descr(class_doc.descr, ' ')) 103 else: 104 out(self._descr(class_doc.descr, prefix)) 105 106 # List of nested classes in this class. 107 self.write_list(out, 'Methods', class_doc, 108 value_type='instancemethod', prefix=prefix, 109 noindent=len(prefix)>4) 110 self.write_list(out, 'Class Methods', class_doc, 111 value_type='classmethod', prefix=prefix) 112 self.write_list(out, 'Static Methods', class_doc, 113 value_type='staticmethod', prefix=prefix) 114 self.write_list(out, 'Nested Classes', class_doc, 115 value_type='class', prefix=prefix) 116 self.write_list(out, 'Instance Variables', class_doc, 117 value_type='instancevariable', prefix=prefix) 118 self.write_list(out, 'Class Variables', class_doc, 119 value_type='classvariable', prefix=prefix) 120 121 self.write_list(out, 'Inherited Methods', class_doc, 122 value_type='method', prefix=prefix, 123 inherited=True, verbose=False) 124 self.write_list(out, 'Inherited Instance Variables', class_doc, 125 value_type='instancevariable', prefix=prefix, 126 inherited=True, verbose=False) 127 self.write_list(out, 'Inherited Class Variables', class_doc, 128 value_type='classvariable', prefix=prefix, 129 inherited=True, verbose=False) 130 self.write_list(out, 'Inherited Nested Classes', class_doc, 131 value_type='class', prefix=prefix, 132 inherited=True, verbose=False)
    133
    134 - def write_variable(self, out, var_doc, name=None, prefix='', verbose=True):
    135 if name is None: name = var_doc.name 136 out(prefix+self.bold(str(name))) 137 if (var_doc.value not in (UNKNOWN, None) and 138 var_doc.is_alias is True and 139 var_doc.value.canonical_name not in (None, UNKNOWN)): 140 out(' = %s' % var_doc.value.canonical_name) 141 elif var_doc.value not in (UNKNOWN, None): 142 val_repr = var_doc.value.summary_pyval_repr( 143 max_len=self._cols-len(name)-len(prefix)-3) 144 out(' = %s' % val_repr.to_plaintext(None)) 145 out('\n') 146 if not verbose: return 147 prefix += ' ' # indent the body. 148 if var_doc.descr not in (None, '', UNKNOWN): 149 out(self._descr(var_doc.descr, prefix))
    150
    151 - def write_property(self, out, prop_doc, name=None, prefix='', 152 verbose=True):
    153 if name is None: name = prop_doc.canonical_name 154 out(prefix+self.bold(str(name))) 155 if not verbose: return 156 prefix += ' ' # indent the body. 157 158 if prop_doc.descr not in (None, '', UNKNOWN): 159 out(self._descr(prop_doc.descr, prefix))
    160 161
    162 - def write_function(self, out, func_doc, name=None, prefix='', 163 verbose=True):
    164 if name is None: name = func_doc.canonical_name 165 self.write_signature(out, func_doc, name, prefix) 166 if not verbose: return 167 168 prefix += ' ' # indent the body. 169 170 if func_doc.descr not in (None, '', UNKNOWN): 171 out(self._descr(func_doc.descr, prefix)) 172 173 if func_doc.return_descr not in (None, '', UNKNOWN): 174 out(self.section('Returns:', prefix)) 175 out(self._descr(func_doc.return_descr, prefix+' ')) 176 177 if func_doc.return_type not in (None, '', UNKNOWN): 178 out(self.section('Return Type:', prefix)) 179 out(self._descr(func_doc.return_type, prefix+' '))
    180
    181 - def write_signature(self, out, func_doc, name, prefix):
    182 args = [self.fmt_arg(argname, default) for (argname, default) 183 in zip(func_doc.posargs, func_doc.posarg_defaults)] 184 if func_doc.vararg: args.append('*'+func_doc.vararg) 185 if func_doc.kwarg: args.append('**'+func_doc.kwarg) 186 187 out(prefix+self.bold(str(name))+'(') 188 x = left = len(prefix) + len(name) + 1 189 for i, arg in enumerate(args): 190 if x > left and x+len(arg) > 75: 191 out('\n'+prefix + ' '*len(name) + ' ') 192 x = left 193 out(arg) 194 x += len(arg) 195 if i < len(args)-1: 196 out(', ') 197 x += 2 198 out(')\n')
    199 200 # [xx] tuple args!
    201 - def fmt_arg(self, name, default):
    202 if default is None: 203 return '%s' % name 204 else: 205 default_repr = default.summary_pyval_repr() 206 return '%s=%s' % (name, default_repr.to_plaintext(None))
    207
    208 - def write_list(self, out, heading, doc, value_type=None, imported=False, 209 inherited=False, prefix='', noindent=False, 210 verbose=True):
    211 # Get a list of the VarDocs we should describe. 212 if isinstance(doc, ClassDoc): 213 var_docs = doc.select_variables(value_type=value_type, 214 imported=imported, 215 inherited=inherited) 216 else: 217 var_docs = doc.select_variables(value_type=value_type, 218 imported=imported) 219 if not var_docs: return 220 221 out(prefix+'\n') 222 if not noindent: 223 out(self.section(heading, prefix)) 224 prefix += ' ' 225 226 for i, var_doc in enumerate(var_docs): 227 val_doc, name = var_doc.value, var_doc.name 228 229 if verbose: 230 out(prefix+'\n') 231 232 # hmm: 233 if not verbose: 234 if isinstance(doc, ClassDoc): 235 name = var_doc.canonical_name 236 elif val_doc not in (None, UNKNOWN): 237 name = val_doc.canonical_name 238 239 if isinstance(val_doc, RoutineDoc): 240 self.write_function(out, val_doc, name, prefix, verbose) 241 elif isinstance(val_doc, PropertyDoc): 242 self.write_property(out, val_doc, name, prefix, verbose) 243 elif isinstance(val_doc, ClassDoc): 244 self.write_class(out, val_doc, name, prefix, verbose) 245 else: 246 self.write_variable(out, var_doc, name, prefix, verbose)
    247
    248 - def _descr(self, descr, prefix):
    249 s = descr.to_plaintext(None, indent=len(prefix)).rstrip() 250 s = '\n'.join([(prefix+l[len(prefix):]) for l in s.split('\n')]) 251 return s+'\n'#+prefix+'\n'
    252 253 254 # def drawline(self, s, x): 255 # s = re.sub(r'(?m)^(.{%s}) ' % x, r'\1|', s) 256 # return re.sub(r'(?m)^( {,%s})$(?=\n)' % x, x*' '+'|', s) 257 258 259 #//////////////////////////////////////////////////////////// 260 # Helpers 261 #//////////////////////////////////////////////////////////// 262
    263 - def bold(self, text):
    264 """Write a string in bold by overstriking.""" 265 return ''.join([ch+'\b'+ch for ch in text])
    266
    267 - def title(self, text, indent):
    268 return ' '*indent + self.bold(text.capitalize()) + '\n\n'
    269
    270 - def section(self, text, indent=''):
    271 if indent == '': 272 return indent + self.bold(text.upper()) + '\n' 273 else: 274 return indent + self.bold(text.capitalize()) + '\n'
    275

    epydoc-3.0.1+dfsg/doc/api/epydoc.cli-module.html0000644000175000017500000011533710750103050021716 0ustar pronovicpronovic epydoc.cli
    Package epydoc :: Module cli
    [hide private]
    [frames] | no frames]

    Module cli

    source code

    Command-line interface for epydoc. Abbreviated Usage:

    epydoc [options] NAMES...
    
        NAMES...                  The Python modules to document.
        --html                    Generate HTML output (default).
        --latex                   Generate LaTeX output.
        --pdf                     Generate pdf output, via LaTeX.
        -o DIR, --output DIR      The output directory.
        --inheritance STYLE       The format for showing inherited objects.
        -V, --version             Print the version of epydoc.
        -h, --help                Display a usage message.
    

    Run "epydoc --help" for a complete option list. See the epydoc(1) man page for more information.

    Config Files

    Configuration files can be specified with the --config option. These files are read using ConfigParser. Configuration files may set options or add names of modules to document. Option names are (usually) identical to the long names of command line options. To specify names to document, use any of the following option names:

     module modules value values object objects
    

    A simple example of a config file is:

     [epydoc]
     modules: sys, os, os.path, re, %(MYSANDBOXPATH)/utilities.py
     name: Example
     graph: classtree
     introspect: no
    

    All ConfigParser interpolations are done using local values and the environment variables.

    Verbosity Levels

    The -v and -q options increase and decrease verbosity, respectively. The default verbosity level is zero. The verbosity levels are currently defined as follows:

                   Progress    Markup warnings   Warnings   Errors
    -3               none            no             no        no
    -2               none            no             no        yes
    -1               none            no             yes       yes
     0 (default)     bar             no             yes       yes
     1               bar             yes            yes       yes
     2               list            yes            yes       yes
    
    Classes [hide private]
        Logging
      TerminalController
    A class that can be used to portably generate formatted output to a terminal.
      ConsoleLogger
      UnifiedProgressConsoleLogger
      HTMLLogger
    A logger used to generate a log of all warnings and messages to an HTML file.
    Functions [hide private]
        Argument & Config File Parsing
     
    parse_arguments() source code
     
    parse_configfiles(configfiles, options, names) source code
     
    _str_to_bool(val, optname) source code
     
    _str_to_int(val, optname) source code
     
    _str_to_list(val) source code
        Interface
     
    main(options, names) source code
     
    write_html(docindex, options) source code
     
    write_pickle(docindex, options)
    Helper for writing output to a pickle file, which can then be read in at a later time.
    source code
     
    pickle_persistent_id(obj)
    Helper for pickling, which allows us to save and restore UNKNOWN, which is required to be identical to apidoc.UNKNOWN.
    source code
     
    pickle_persistent_load(identifier)
    Helper for pickling, which allows us to save and restore UNKNOWN, which is required to be identical to apidoc.UNKNOWN.
    source code
     
    write_latex(docindex, options, format) source code
     
    write_text(docindex, options) source code
     
    check_docs(docindex, options) source code
     
    cli() source code
     
    _profile() source code
    Variables [hide private]
      INHERITANCE_STYLES = ('grouped', 'listed', 'included')
      GRAPH_TYPES = ('classtree', 'callgraph', 'umlclasstree')
      ACTIONS = ('html', 'text', 'latex', 'dvi', 'ps', 'pdf', 'check')
      DEFAULT_DOCFORMAT = 'epytext'
      PROFILER = 'profile'
    Which profiler to use: 'hotshot' or 'profile'
      descr = 'Black on white, with blue highlights'
      key = 'white'
      sheet = '\n\n/* Epydoc CSS Stylesheet\n *\n * This stylesheet ...
      topic = 'inheritance'
        Help Topics
      DOCFORMATS = ('epytext', 'plaintext', 'restructuredtext', 'jav...
      HELP_TOPICS = {'css': 'The following built-in CSS stylesheets ...
        Argument & Config File Parsing
      OPTION_DEFAULTS = {'action': 'html', 'debug': True, 'docformat...
        Interface
      _RERUN_LATEX_RE = re.compile(r'(?im)^LaTeX\s+Warning:\s+Label\...
    Function Details [hide private]

    write_pickle(docindex, options)

    source code 

    Helper for writing output to a pickle file, which can then be read in at a later time. But loading the pickle is only marginally faster than building the docs from scratch, so this has pretty limited application.


    Variables Details [hide private]

    DOCFORMATS

    Value:
    ('epytext', 'plaintext', 'restructuredtext', 'javadoc')
    

    HELP_TOPICS

    Value:
    {'css': '''The following built-in CSS stylesheets are available:
            blue: Black on steel blue
         default: Default stylesheet (=white)
       grayscale: Grayscale black on white
           black: White on black, with blue highlights
           green: Black on green
           white: Black on white, with blue highlights''',
     'docformat': '''__docformat__ is a module variable that specifies the\
    ...
    

    OPTION_DEFAULTS

    Value:
    {'action': 'html',
     'debug': True,
     'docformat': 'epytext',
     'exclude': [],
     'exclude_introspect': [],
     'exclude_parse': [],
     'external_api': [],
     'external_api_file': [],
    ...
    

    _RERUN_LATEX_RE

    Value:
    re.compile(r'(?im)^LaTeX\s+Warning:\s+Label\(s\)\s+may\s+have\s+change\
    d.\s+Rerun')
    

    sheet

    Value:
    '''
    
    /* Epydoc CSS Stylesheet
     *
     * This stylesheet can be used to customize the appearance of epydoc\'\
    s
     * HTML output.
     *
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docparser-module.html0000644000175000017500000063421710750103050023134 0ustar pronovicpronovic epydoc.docparser
    Package epydoc :: Module docparser
    [hide private]
    [frames] | no frames]

    Module docparser

    source code

    Extract API documentation about python objects by parsing their source code.

    The function parse_docs(), which provides the main interface of this module, reads and parses the Python source code for a module, and uses it to create an APIDoc object containing the API documentation for the variables and values defined in that modules.

    Currently, parse_docs() extracts documentation from the following source code constructions:

    • module docstring
    • import statements
    • class definition blocks
    • function definition blocks
    • assignment statements
      • simple assignment statements
      • assignment statements with multiple '='s
      • assignment statements with unpacked left-hand sides
      • assignment statements that wrap a function in classmethod or staticmethod.
      • assignment to special variables __path__, __all__, and __docformat__.
    • delete statements

    parse_docs() does not yet support the following source code constructions:

    • assignment statements that create properties

    By default, parse_docs() will expore the contents of top-level try and if blocks. If desired, parse_docs() can also be configured to explore the contents of while and for blocks. (See the configuration constants, below.)


    To Do: Make it possible to extend the functionality of parse_docs(), by replacing process_line with a dispatch table that can be customized (similarly to docintrospector.register_introspector()).

    Classes [hide private]
      ParseError
    An exception that is used to signify that docparser encountered syntactically invalid Python code while processing a Python source file.
    Functions [hide private]
        Module parser
    ValueDoc
    parse_docs(filename=None, name=None, context=None, is_script=False)
    Generate the API documentation for a specified object by parsing Python source files, and return it as a ValueDoc.
    source code
    call graph 
     
    _parse_package(package_dir)
    If the given directory is a package directory, then parse its __init__.py file (and the __init__.py files of all ancestor packages); and return its ModuleDoc.
    source code
    call graph 
     
    handle_special_module_vars(module_doc) source code
    call graph 
     
    _module_var_toktree(module_doc, name) source code
    call graph 
        Module Lookup
     
    _find(name, package_doc=None)
    Return the API documentaiton for the object whose name is name.
    source code
    call graph 
     
    _is_submodule_import_var(module_doc, var_name)
    Return true if var_name is the name of a variable in module_doc that just contains an imported_from link to a submodule of the same name.
    source code
    call graph 
     
    _find_in_namespace(name, namespace_doc) source code
    call graph 
     
    _get_filename(identifier, path=None) source code
    call graph 
        File tokenization loop
     
    process_file(module_doc)
    Read the given ModuleDoc's file, and add variables corresponding to any objects defined in that file.
    source code
    call graph 
     
    add_to_group(container, api_doc, group_name) source code
    call graph 
     
    script_guard(line)
    Detect the idiomatic trick if __name__ == "__main__":
    source code
    call graph 
        Shallow parser
     
    shallow_parse(line_toks)
    Given a flat list of tokens, return a nested tree structure (called a token tree), whose leaves are identical to the original list, but whose structure reflects the structure implied by the grouping tokens (i.e., parenthases, braces, and brackets).
    source code
    call graph 
        Line processing
     
    process_line(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    Returns: new-doc, decorator..?
    source code
    call graph 
     
    process_control_flow_line(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding) source code
    call graph 
     
    process_import(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding) source code
    call graph 
     
    process_from_import(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding) source code
    call graph 
     
    _process_fromstar_import(src, parent_docs)
    Handle a statement of the form:
    source code
    call graph 
     
    _import_var(name, parent_docs)
    Handle a statement of the form:
    source code
    call graph 
     
    _import_var_as(src, name, parent_docs)
    Handle a statement of the form:
    source code
    call graph 
     
    _add_import_var(src, name, container)
    Add a new imported variable named name to container, with imported_from=src.
    source code
    call graph 
     
    _global_name(name, parent_docs)
    If the given name is package-local (relative to the current context, as determined by parent_docs), then convert it to a global name.
    source code
    call graph 
     
    process_assignment(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding) source code
    call graph 
     
    lhs_is_instvar(lhs_pieces, parent_docs) source code
    call graph 
     
    rhs_to_valuedoc(rhs, parent_docs) source code
    call graph 
     
    get_lhs_parent(lhs_name, parent_docs) source code
    call graph 
     
    process_one_line_block(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for single-line blocks, such as:
    source code
    call graph 
     
    process_multi_stmt(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for semicolon-separated statements, such as:
    source code
    call graph 
     
    process_del(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for delete statements, such as:
    source code
    call graph 
     
    process_docstring(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for bare string literals.
    source code
    call graph 
     
    process_funcdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for function declaration lines, such as:
    source code
    call graph 
     
    apply_decorator(decorator_name, func_doc) source code
    call graph 
     
    init_arglist(func_doc, arglist) source code
    call graph 
     
    process_classdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)
    The line handler for class declaration lines, such as:
    source code
    call graph 
     
    _proxy_base(**attribs) source code
    call graph 
     
    find_base(name, parent_docs) source code
    call graph 
        Parsing
     
    dotted_names_in(elt_list)
    Return a list of all simple dotted names in the given expression.
    source code
    call graph 
     
    parse_name(elt, strip_parens=False)
    If the given token tree element is a name token, then return that name as a string.
    source code
    call graph 
     
    parse_dotted_name(elt_list, strip_parens=True, parent_name=None) source code
    call graph 
     
    split_on(elt_list, split_tok) source code
    call graph 
     
    parse_funcdef_arg(elt)
    If the given tree token element contains a valid function definition argument (i.e., an identifier token or nested list of identifiers), then return a corresponding string identifier or nested list of string identifiers.
    source code
    call graph 
     
    parse_classdef_bases(elt)
    If the given tree token element contains a valid base list (that contains only dotted names), then return a corresponding list of DottedNames.
    source code
    call graph 
     
    parse_dotted_name_list(elt_list)
    If the given list of tree token elements contains a comma-separated list of dotted names, then return a corresponding list of DottedName objects.
    source code
     
    parse_string(elt_list) source code
    call graph 
     
    parse_string_list(elt_list) source code
    call graph 
        Variable Manipulation
     
    set_variable(namespace, var_doc, preserve_docstring=False)
    Add var_doc to namespace.
    source code
    call graph 
     
    del_variable(namespace, name) source code
    call graph 
        Name Lookup
    VariableDoc or None
    lookup_name(identifier, parent_docs)
    Find and return the documentation for the variable named by the given identifier.
    source code
    call graph 
     
    lookup_variable(dotted_name, parent_docs) source code
    call graph 
     
    lookup_value(dotted_name, parent_docs)
    Find and return the documentation for the value contained in the variable with the given name in the current namespace.
    source code
    call graph 
        Docstring Comments
     
    add_docstring_from_comments(api_doc, comments) source code
    call graph 
        Tree tokens
     
    _join_toktree(s1, s2) source code
     
    _pp_toktree_add_piece(spacing, pieces, piece) source code
    call graph 
     
    pp_toktree(elts, spacing='normal', indent=0) source code
    call graph 
     
    _pp_toktree(elts, spacing, indent, pieces) source code
    call graph 
        Helper Functions
     
    get_module_encoding(filename) source code
    call graph 
     
    _get_module_name(filename, package_doc)
    Return (dotted_name, is_package)
    source code
    call graph 
     
    flatten(lst, out=None)
    Returns: a flat list containing the leaves of the given nested list.
    source code
    Variables [hide private]
    dict _moduledoc_cache = {'/home/edloper/newdata/projects/docutils/d...
    A cache of ModuleDocs that we've already created.
        Configuration Constants: Control Flow
      PARSE_TRY_BLOCKS = True
    Should the contents of try blocks be examined?
      PARSE_EXCEPT_BLOCKS = True
    Should the contents of except blocks be examined?
      PARSE_FINALLY_BLOCKS = True
    Should the contents of finally blocks be examined?
      PARSE_IF_BLOCKS = True
    Should the contents of if blocks be examined?
      PARSE_ELSE_BLOCKS = True
    Should the contents of else and elif blocks be examined?
      PARSE_WHILE_BLOCKS = False
    Should the contents of while blocks be examined?
      PARSE_FOR_BLOCKS = False
    Should the contents of for blocks be examined?
        Configuration Constants: Imports
      IMPORT_HANDLING = 'link'
    What should docparser do when it encounters an import statement?
      IMPORT_STAR_HANDLING = 'parse'
    When docparser encounters a 'from m import *' statement, and is unable to parse m (either because IMPORT_HANDLING='link', or because parsing failed), how should it determine the list of identifiers expored by m?
      DEFAULT_DECORATOR_BEHAVIOR = 'transparent'
    When DocParse encounters an unknown decorator, what should it do to the documentation of the decorated function?
      BASE_HANDLING = 'parse'
    What should docparser do when it encounters a base class that was imported from another module?
        Configuration Constants: Comment docstrings
      COMMENT_DOCSTRING_MARKER = '#:'
    The prefix used to mark comments that contain attribute docstrings for variables.
        Configuration Constants: Grouping
      START_GROUP_MARKER = '#{'
    The prefix used to mark a comment that starts a group.
      END_GROUP_MARKER = '#}'
    The prefix used to mark a comment that ends a group.
        Line processing
      CONTROL_FLOW_KEYWORDS = ['if', 'elif', 'else', 'while', 'for',...
    A list of the control flow keywords.
    Function Details [hide private]

    parse_docs(filename=None, name=None, context=None, is_script=False)

    source code 
    call graph 

    Generate the API documentation for a specified object by parsing Python source files, and return it as a ValueDoc. The object to generate documentation for may be specified using the filename parameter or the name parameter. (It is an error to specify both a filename and a name; or to specify neither a filename nor a name).

    Parameters:
    • filename - The name of the file that contains the python source code for a package, module, or script. If filename is specified, then parse will return a ModuleDoc describing its contents.
    • name - The fully-qualified python dotted name of any value (including packages, modules, classes, and functions). parse_docs() will automatically figure out which module(s) it needs to parse in order to find the documentation for the specified object.
    • context - The API documentation for the package that contains filename. If no context is given, then filename is assumed to contain a top-level module or package. It is an error to specify a context if the name argument is used.
    Returns: ValueDoc

    _find(name, package_doc=None)

    source code 
    call graph 

    Return the API documentaiton for the object whose name is name. package_doc, if specified, is the API documentation for the package containing the named object.

    _is_submodule_import_var(module_doc, var_name)

    source code 
    call graph 

    Return true if var_name is the name of a variable in module_doc that just contains an imported_from link to a submodule of the same name. (I.e., is a variable created when a package imports one of its own submodules.)

    process_file(module_doc)

    source code 
    call graph 

    Read the given ModuleDoc's file, and add variables corresponding to any objects defined in that file. In particular, read and tokenize module_doc.filename, and process each logical line using process_line().

    shallow_parse(line_toks)

    source code 
    call graph 

    Given a flat list of tokens, return a nested tree structure (called a token tree), whose leaves are identical to the original list, but whose structure reflects the structure implied by the grouping tokens (i.e., parenthases, braces, and brackets). If the parenthases, braces, and brackets do not match, or are not balanced, then raise a ParseError.

    Assign some structure to a sequence of structure (group parens).

    process_line(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 
    Returns:
    new-doc, decorator..?

    _process_fromstar_import(src, parent_docs)

    source code 
    call graph 

    Handle a statement of the form:

    >>> from <src> import *

    If IMPORT_HANDLING is 'parse', then first try to parse the module <src>, and copy all of its exported variables to parent_docs[-1].

    Otherwise, try to determine the names of the variables exported by <src>, and create a new variable for each export. If IMPORT_STAR_HANDLING is 'parse', then the list of exports if found by parsing <src>; if it is 'introspect', then the list of exports is found by importing and introspecting <src>.

    _import_var(name, parent_docs)

    source code 
    call graph 

    Handle a statement of the form:

    >>> import <name>

    If IMPORT_HANDLING is 'parse', then first try to find the value by parsing; and create an appropriate variable in parentdoc.

    Otherwise, add a variable for the imported variable. (More than one variable may be created for cases like 'import a.b', where we need to create a variable 'a' in parentdoc containing a proxy module; and a variable 'b' in the proxy module.

    _import_var_as(src, name, parent_docs)

    source code 
    call graph 

    Handle a statement of the form:

    >>> import src as name

    If IMPORT_HANDLING is 'parse', then first try to find the value by parsing; and create an appropriate variable in parentdoc.

    Otherwise, create a variables with its imported_from attribute pointing to the imported object.

    process_one_line_block(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for single-line blocks, such as:

    >>> def f(x): return x*2

    This handler calls process_line twice: once for the tokens up to and including the colon, and once for the remaining tokens. The comment docstring is applied to the first line only.

    Returns:
    None

    process_multi_stmt(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for semicolon-separated statements, such as:

    >>> x=1; y=2; z=3

    This handler calls process_line once for each statement. The comment docstring is not passed on to any of the sub-statements.

    Returns:
    None

    process_del(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for delete statements, such as:

    >>> del x, y.z

    This handler calls del_variable for each dotted variable in the variable list. The variable list may be nested. Complex expressions in the variable list (such as x[3]) are ignored.

    Returns:
    None

    process_docstring(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for bare string literals. If prev_line_doc is not None, then the string literal is added to that APIDoc as a docstring. If it already has a docstring (from comment docstrings), then the new docstring will be appended to the old one.

    process_funcdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for function declaration lines, such as:

    >>> def f(a, b=22, (c,d)):

    This handler creates and initializes a new VariableDoc containing a RoutineDoc, adds the VariableDoc to the containing namespace, and returns the RoutineDoc.

    process_classdef(line, parent_docs, prev_line_doc, lineno, comments, decorators, encoding)

    source code 
    call graph 

    The line handler for class declaration lines, such as:

    >>> class Foo(Bar, Baz):

    This handler creates and initializes a new VariableDoc containing a ClassDoc, adds the VariableDoc to the containing namespace, and returns the ClassDoc.

    parse_name(elt, strip_parens=False)

    source code 
    call graph 

    If the given token tree element is a name token, then return that name as a string. Otherwise, raise ParseError.

    Parameters:
    • strip_parens - If true, then if elt is a single name enclosed in parenthases, then return that name.

    parse_dotted_name(elt_list, strip_parens=True, parent_name=None)

    source code 
    call graph 
    Parameters:
    • parent_name (DottedName) - canonical name of referring module, to resolve relative imports.

    Bug: does not handle 'x.(y).z'

    parse_funcdef_arg(elt)

    source code 
    call graph 

    If the given tree token element contains a valid function definition argument (i.e., an identifier token or nested list of identifiers), then return a corresponding string identifier or nested list of string identifiers. Otherwise, raise a ParseError.

    parse_classdef_bases(elt)

    source code 
    call graph 

    If the given tree token element contains a valid base list (that contains only dotted names), then return a corresponding list of DottedNames. Otherwise, raise a ParseError.

    Bug: Does not handle either of:

       - class A( (base.in.parens) ): pass
       - class B( (lambda:calculated.base)() ): pass
    

    parse_dotted_name_list(elt_list)

    source code 

    If the given list of tree token elements contains a comma-separated list of dotted names, then return a corresponding list of DottedName objects. Otherwise, raise ParseError.

    set_variable(namespace, var_doc, preserve_docstring=False)

    source code 
    call graph 

    Add var_doc to namespace. If namespace already contains a variable with the same name, then discard the old variable. If preserve_docstring is true, then keep the old variable's docstring when overwriting a variable.

    get_module_encoding(filename)

    source code 
    call graph 

    See Also: PEP 263

    flatten(lst, out=None)

    source code 
    Parameters:
    • lst - The nested list that should be flattened.
    Returns:
    a flat list containing the leaves of the given nested list.

    Variables Details [hide private]

    _moduledoc_cache

    A cache of ModuleDocs that we've already created. _moduledoc_cache is a dictionary mapping from filenames to ValueDoc objects.

    Type:
    dict
    Value:
    {'/home/edloper/newdata/projects/docutils/docutils/__init__.py': <Modu\
    leDoc docutils>,
     '/home/edloper/newdata/projects/docutils/docutils/nodes.py': <ModuleD\
    oc docutils.nodes>,
     '/home/edloper/newdata/projects/docutils/docutils/utils.py': <ModuleD\
    oc docutils.utils>,
     '/home/edloper/newdata/projects/docutils/docutils/writers/__init__.py\
    ': <ModuleDoc docutils.writers>,
    ...
    

    IMPORT_HANDLING

    What should docparser do when it encounters an import statement?

    • 'link': Create variabledoc objects with imported_from pointers to the source object.
    • 'parse': Parse the imported file, to find the actual documentation for the imported object. (This will fall back to the 'link' behavior if the imported file can't be parsed, e.g., if it's a builtin.)
    Value:
    'link'
    

    IMPORT_STAR_HANDLING

    When docparser encounters a 'from m import *' statement, and is unable to parse m (either because IMPORT_HANDLING='link', or because parsing failed), how should it determine the list of identifiers expored by m?

    • 'ignore': ignore the import statement, and don't create any new variables.
    • 'parse': parse it to find a list of the identifiers that it exports. (This will fall back to the 'ignore' behavior if the imported file can't be parsed, e.g., if it's a builtin.)
    • 'introspect': import the module and introspect it (using dir) to find a list of the identifiers that it exports. (This will fall back to the 'ignore' behavior if the imported file can't be parsed, e.g., if it's a builtin.)
    Value:
    'parse'
    

    DEFAULT_DECORATOR_BEHAVIOR

    When DocParse encounters an unknown decorator, what should it do to the documentation of the decorated function?

    • 'transparent': leave the function's documentation as-is.
    • 'opaque': replace the function's documentation with an empty ValueDoc object, reflecting the fact that we have no knowledge about what value the decorator returns.
    Value:
    'transparent'
    

    BASE_HANDLING

    What should docparser do when it encounters a base class that was imported from another module?

    • 'link': Create a valuedoc with a proxy_for pointer to the base class.
    • 'parse': Parse the file containing the base class, to find the actual documentation for it. (This will fall back to the 'link' behavior if the imported file can't be parsed, e.g., if it's a builtin.)
    Value:
    'parse'
    

    START_GROUP_MARKER

    The prefix used to mark a comment that starts a group. This marker should be followed (on the same line) by the name of the group. Following a start-group comment, all variables defined at the same indentation level will be assigned to this group name, until the parser reaches the end of the file, a matching end-group comment, or another start-group comment at the same indentation level.

    Value:
    '#{'
    

    END_GROUP_MARKER

    The prefix used to mark a comment that ends a group. See START_GROUP_MARKER.

    Value:
    '#}'
    

    CONTROL_FLOW_KEYWORDS

    A list of the control flow keywords. If a line begins with one of these keywords, then it should be handled by process_control_flow_line.

    Value:
    ['if', 'elif', 'else', 'while', 'for', 'try', 'except', 'finally']
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.javadoc.ParsedJavadocDocstring-class.html0000644000175000017500000007651210750103050030257 0ustar pronovicpronovic epydoc.markup.javadoc.ParsedJavadocDocstring
    Package epydoc :: Package markup :: Module javadoc :: Class ParsedJavadocDocstring
    [hide private]
    [frames] | no frames]

    Class ParsedJavadocDocstring

    source code


    An encoded version of a Javadoc docstring. Since Javadoc is a fairly simple markup language, we don't do any processing in advance; instead, we wait to split fields or resolve crossreference links until we need to.

    Instance Methods [hide private]
     
    __init__(self, docstring, errors=None)
    Create a new ParsedJavadocDocstring.
    source code
     
    _check_links(self, errors)
    Make sure that all @{link}s are valid.
    source code
    string
    to_plaintext(self, docstring_linker, **options)
    Translate this docstring to plaintext.
    source code
    (ParsedDocstring, bool)
    summary(self)
    Returns: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary.
    source code

    Inherited from ParsedDocstring: __add__, concatenate, index_terms, to_latex

        Field Splitting
    (ParsedDocstring, list of Field)
    split_fields(self, errors=None)
    Split this docstring into its body and its fields.
    source code
        HTML Output
    string
    to_html(self, docstring_linker, **options)
    Translate this docstring to HTML.
    source code
    Class Variables [hide private]
      _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)')
        Field Splitting
      _ARG_FIELDS = ['group', 'variable', 'var', 'type', 'cvariable'...
    A list of the fields that take arguments.
      _FIELD_RE = re.compile(r'(?m)(^\s*@\w+[\s\$])')
    A regular expression used to search for Javadoc block tags.
        HTML Output
      _LINK_SPLIT_RE = re.compile(r'(\{@link(?:plain)?\s[^\}]+\})')
    A regular expression used to search for Javadoc inline tags.
      _LINK_RE = re.compile(r'\{@link(?:plain)?\s+([\w#\.]+)(?:\([^\...
    A regular expression used to process Javadoc inline tags.
    Method Details [hide private]

    __init__(self, docstring, errors=None)
    (Constructor)

    source code 

    Create a new ParsedJavadocDocstring.

    Parameters:
    • docstring (string) - The docstring that should be used to construct this ParsedJavadocDocstring.
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored. If no list is given, then all errors are ignored.

    split_fields(self, errors=None)

    source code 

    Split this docstring into its body and its fields.

    Parameters:
    • errors - A list where any errors generated during splitting will be stored. If no list is specified, then errors will be ignored.
    Returns: (ParsedDocstring, list of Field)
    A tuple (body, fields), where body is the main body of this docstring, and fields is a list of its fields. If the resulting body is empty, return None for the body.
    Overrides: ParsedDocstring.split_fields
    (inherited documentation)

    to_html(self, docstring_linker, **options)

    source code 

    Translate this docstring to HTML.

    Parameters:
    • docstring_linker - An HTML translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    An HTML fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_html
    (inherited documentation)

    _check_links(self, errors)

    source code 

    Make sure that all @{link}s are valid. We need a separate method for ths because we want to do this at parse time, not html output time. Any errors found are appended to errors.

    to_plaintext(self, docstring_linker, **options)

    source code 

    Translate this docstring to plaintext.

    Parameters:
    • docstring_linker - A plaintext translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A plaintext fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_plaintext
    (inherited documentation)

    summary(self)

    source code 
    Returns: (ParsedDocstring, bool)
    A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring.
    Overrides: ParsedDocstring.summary
    (inherited documentation)

    Class Variable Details [hide private]

    _ARG_FIELDS

    A list of the fields that take arguments. Since Javadoc doesn't mark arguments in any special way, we must consult this list to decide whether the first word of a field is an argument or not.
    Value:
    ['group',
     'variable',
     'var',
     'type',
     'cvariable',
     'cvar',
     'ivariable',
     'ivar',
    ...
    

    _LINK_RE

    A regular expression used to process Javadoc inline tags.
    Value:
    re.compile(r'\{@link(?:plain)?\s+([\w#\.]+)(?:\([^\)]*\))?(\s+.*)?\}')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest.LaTeXDoctestColorizer-class.html0000644000175000017500000004222310750103050030116 0ustar pronovicpronovic epydoc.markup.doctest.LaTeXDoctestColorizer
    Package epydoc :: Package markup :: Module doctest :: Class LaTeXDoctestColorizer
    [hide private]
    [frames] | no frames]

    Class LaTeXDoctestColorizer

    source code


    A subclass of DoctestColorizer that generates LaTeX output.

    Instance Methods [hide private]
     
    markup(self, s, tag)
    Apply syntax highlighting to a single substring from a doctest block.
    source code

    Inherited from DoctestColorizer: colorize_codeblock, colorize_doctest, colorize_inline, subfunc

    Class Variables [hide private]
      PREFIX = '\\begin{alltt}\n'
    A string that is added to the beginning of the strings returned by colorize_codeblock and colorize_doctest.
      SUFFIX = '\\end{alltt}\n'
    A string that is added to the end of the strings returned by colorize_codeblock and colorize_doctest.

    Inherited from DoctestColorizer: DOCTEST_DIRECTIVE_RE, DOCTEST_EXAMPLE_RE, DOCTEST_RE, EXCEPT_RE, PROMPT2_RE, PROMPT_RE

    Method Details [hide private]

    markup(self, s, tag)

    source code 

    Apply syntax highlighting to a single substring from a doctest block. s is the substring, and tag is the tag that should be applied to the substring. tag will be one of the following strings:

    • prompt -- the Python PS1 prompt (>>>)
    • more -- the Python PS2 prompt (...)
    • keyword -- a Python keyword (for, if, etc.)
    • builtin -- a Python builtin name (abs, dir, etc.)
    • string -- a string literal
    • comment -- a comment
    • except -- an exception traceback (up to the next >>>)
    • output -- the output from a doctest block.
    • defname -- the name of a function or class defined by a def or class statement.
    • other -- anything else (does *not* include output.)
    Overrides: DoctestColorizer.markup
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_help-pysrc.html0000644000175000017500000010226710750103050024775 0ustar pronovicpronovic epydoc.docwriter.html_help
    Package epydoc :: Package docwriter :: Module html_help
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.html_help

      1  # 
      2  # epydoc.css: default help page 
      3  # Edward Loper 
      4  # 
      5  # Created [01/30/01 05:18 PM] 
      6  # $Id: html_help.py 1239 2006-07-05 11:29:50Z edloper $ 
      7  # 
      8   
      9  """ 
     10  Default help file for the HTML outputter (L{epydoc.docwriter.html}). 
     11   
     12  @type HTML_HELP: C{string} 
     13  @var HTML_HELP: The contents of the HTML body for the default 
     14  help page. 
     15  """ 
     16  __docformat__ = 'epytext en' 
     17   
     18  # Expects: {'this_project': name} 
     19  HTML_HELP = ''' 
     20  <h1 class="epydoc"> API Documentation </h1> 
     21   
     22  <p> This document contains the API (Application Programming Interface) 
     23  documentation for %(this_project)s.  Documentation for the Python 
     24  objects defined by the project is divided into separate pages for each 
     25  package, module, and class.  The API documentation also includes two 
     26  pages containing information about the project as a whole: a trees 
     27  page, and an index page.  </p> 
     28   
     29  <h2> Object Documentation </h2> 
     30   
     31    <p>Each <strong>Package Documentation</strong> page contains: </p> 
     32    <ul> 
     33      <li> A description of the package. </li> 
     34      <li> A list of the modules and sub-packages contained by the 
     35      package.  </li> 
     36      <li> A summary of the classes defined by the package. </li> 
     37      <li> A summary of the functions defined by the package. </li> 
     38      <li> A summary of the variables defined by the package. </li> 
     39      <li> A detailed description of each function defined by the 
     40      package. </li> 
     41      <li> A detailed description of each variable defined by the 
     42      package. </li> 
     43    </ul> 
     44     
     45    <p>Each <strong>Module Documentation</strong> page contains:</p> 
     46    <ul> 
     47      <li> A description of the module. </li> 
     48      <li> A summary of the classes defined by the module. </li> 
     49      <li> A summary of the functions defined by the module. </li> 
     50      <li> A summary of the variables defined by the module. </li> 
     51      <li> A detailed description of each function defined by the 
     52      module. </li> 
     53      <li> A detailed description of each variable defined by the 
     54      module. </li> 
     55    </ul> 
     56     
     57    <p>Each <strong>Class Documentation</strong> page contains: </p> 
     58    <ul> 
     59      <li> A class inheritance diagram. </li> 
     60      <li> A list of known subclasses. </li> 
     61      <li> A description of the class. </li> 
     62      <li> A summary of the methods defined by the class. </li> 
     63      <li> A summary of the instance variables defined by the class. </li> 
     64      <li> A summary of the class (static) variables defined by the 
     65      class. </li>  
     66      <li> A detailed description of each method defined by the 
     67      class. </li> 
     68      <li> A detailed description of each instance variable defined by the 
     69      class. </li>  
     70      <li> A detailed description of each class (static) variable defined 
     71      by the class. </li>  
     72    </ul> 
     73   
     74  <h2> Project Documentation </h2> 
     75   
     76    <p> The <strong>Trees</strong> page contains the module and class hierarchies: </p> 
     77    <ul> 
     78      <li> The <em>module hierarchy</em> lists every package and module, with 
     79      modules grouped into packages.  At the top level, and within each 
     80      package, modules and sub-packages are listed alphabetically. </li> 
     81      <li> The <em>class hierarchy</em> lists every class, grouped by base 
     82      class.  If a class has more than one base class, then it will be 
     83      listed under each base class.  At the top level, and under each base 
     84      class, classes are listed alphabetically. </li> 
     85    </ul> 
     86     
     87    <p> The <strong>Index</strong> page contains indices of terms and 
     88    identifiers: </p> 
     89    <ul> 
     90      <li> The <em>term index</em> lists every term indexed by any object\'s 
     91      documentation.  For each term, the index provides links to each 
     92      place where the term is indexed. </li> 
     93      <li> The <em>identifier index</em> lists the (short) name of every package, 
     94      module, class, method, function, variable, and parameter.  For each 
     95      identifier, the index provides a short description, and a link to 
     96      its documentation. </li> 
     97    </ul> 
     98   
     99  <h2> The Table of Contents </h2> 
    100   
    101  <p> The table of contents occupies the two frames on the left side of 
    102  the window.  The upper-left frame displays the <em>project 
    103  contents</em>, and the lower-left frame displays the <em>module 
    104  contents</em>: </p> 
    105   
    106  <table class="help summary" border="1" cellspacing="0" cellpadding="3"> 
    107    <tr style="height: 30%%"> 
    108      <td align="center" style="font-size: small"> 
    109         Project<br />Contents<hr />...</td> 
    110      <td align="center" style="font-size: small" rowspan="2" width="70%%"> 
    111        API<br />Documentation<br />Frame<br /><br /><br /> 
    112      </td> 
    113    </tr> 
    114    <tr> 
    115      <td align="center" style="font-size: small"> 
    116        Module<br />Contents<hr />&nbsp;<br />...<br />&nbsp; 
    117      </td> 
    118    </tr> 
    119  </table><br /> 
    120   
    121  <p> The <strong>project contents frame</strong> contains a list of all packages 
    122  and modules that are defined by the project.  Clicking on an entry 
    123  will display its contents in the module contents frame.  Clicking on a 
    124  special entry, labeled "Everything," will display the contents of 
    125  the entire project. </p> 
    126   
    127  <p> The <strong>module contents frame</strong> contains a list of every 
    128  submodule, class, type, exception, function, and variable defined by a 
    129  module or package.  Clicking on an entry will display its 
    130  documentation in the API documentation frame.  Clicking on the name of 
    131  the module, at the top of the frame, will display the documentation 
    132  for the module itself. </p> 
    133   
    134  <p> The "<strong>frames</strong>" and "<strong>no frames</strong>" buttons below the top 
    135  navigation bar can be used to control whether the table of contents is 
    136  displayed or not. </p> 
    137   
    138  <h2> The Navigation Bar </h2> 
    139   
    140  <p> A navigation bar is located at the top and bottom of every page. 
    141  It indicates what type of page you are currently viewing, and allows 
    142  you to go to related pages.  The following table describes the labels 
    143  on the navigation bar.  Note that not some labels (such as 
    144  [Parent]) are not displayed on all pages. </p> 
    145   
    146  <table class="summary" border="1" cellspacing="0" cellpadding="3" width="100%%"> 
    147  <tr class="summary"> 
    148    <th>Label</th> 
    149    <th>Highlighted when...</th> 
    150    <th>Links to...</th> 
    151  </tr> 
    152    <tr><td valign="top"><strong>[Parent]</strong></td> 
    153        <td valign="top"><em>(never highlighted)</em></td> 
    154        <td valign="top"> the parent of the current package </td></tr> 
    155    <tr><td valign="top"><strong>[Package]</strong></td> 
    156        <td valign="top">viewing a package</td> 
    157        <td valign="top">the package containing the current object 
    158        </td></tr> 
    159    <tr><td valign="top"><strong>[Module]</strong></td> 
    160        <td valign="top">viewing a module</td> 
    161        <td valign="top">the module containing the current object 
    162        </td></tr>  
    163    <tr><td valign="top"><strong>[Class]</strong></td> 
    164        <td valign="top">viewing a class </td> 
    165        <td valign="top">the class containing the current object</td></tr> 
    166    <tr><td valign="top"><strong>[Trees]</strong></td> 
    167        <td valign="top">viewing the trees page</td> 
    168        <td valign="top"> the trees page </td></tr> 
    169    <tr><td valign="top"><strong>[Index]</strong></td> 
    170        <td valign="top">viewing the index page</td> 
    171        <td valign="top"> the index page </td></tr> 
    172    <tr><td valign="top"><strong>[Help]</strong></td> 
    173        <td valign="top">viewing the help page</td> 
    174        <td valign="top"> the help page </td></tr> 
    175  </table> 
    176   
    177  <p> The "<strong>show private</strong>" and "<strong>hide private</strong>" buttons below 
    178  the top navigation bar can be used to control whether documentation 
    179  for private objects is displayed.  Private objects are usually defined 
    180  as objects whose (short) names begin with a single underscore, but do 
    181  not end with an underscore.  For example, "<code>_x</code>", 
    182  "<code>__pprint</code>", and "<code>epydoc.epytext._tokenize</code>" 
    183  are private objects; but "<code>re.sub</code>", 
    184  "<code>__init__</code>", and "<code>type_</code>" are not.  However, 
    185  if a module defines the "<code>__all__</code>" variable, then its 
    186  contents are used to decide which objects are private. </p> 
    187   
    188  <p> A timestamp below the bottom navigation bar indicates when each 
    189  page was last updated. </p> 
    190  ''' 
    191   
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr._Maxlines-class.html0000644000175000017500000001452110750103050026357 0ustar pronovicpronovic epydoc.markup.pyval_repr._Maxlines
    Package epydoc :: Package markup :: Module pyval_repr :: Class _Maxlines
    [hide private]
    [frames] | no frames]

    Class _Maxlines

    source code


    A control-flow exception that is raised when PyvalColorizer exeeds the maximum number of allowed lines.

    Instance Methods [hide private]

    Inherited from exceptions.Exception: __getitem__, __init__, __str__

    epydoc-3.0.1+dfsg/doc/api/epydoc.css0000644000175000017500000003722710750103050017512 0ustar pronovicpronovic /* Epydoc CSS Stylesheet * * This stylesheet can be used to customize the appearance of epydoc's * HTML output. * */ /* Default Colors & Styles * - Set the default foreground & background color with 'body'; and * link colors with 'a:link' and 'a:visited'. * - Use bold for decision list terms. * - The heading styles defined here are used for headings *within* * docstring descriptions. All headings used by epydoc itself use * either class='epydoc' or class='toc' (CSS styles for both * defined below). */ body { background: #ffffff; color: #000000; } p { margin-top: 0.5em; margin-bottom: 0.5em; } a:link { color: #0000ff; } a:visited { color: #204080; } dt { font-weight: bold; } h1 { font-size: +140%; font-style: italic; font-weight: bold; } h2 { font-size: +125%; font-style: italic; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } code { font-size: 100%; } /* N.B.: class, not pseudoclass */ a.link { font-family: monospace; } /* Page Header & Footer * - The standard page header consists of a navigation bar (with * pointers to standard pages such as 'home' and 'trees'); a * breadcrumbs list, which can be used to navigate to containing * classes or modules; options links, to show/hide private * variables and to show/hide frames; and a page title (using *

    ). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } epydoc-3.0.1+dfsg/doc/api/help.html0000644000175000017500000002603510750103050017326 0ustar pronovicpronovic Help
     
    [hide private]
    [frames] | no frames]

    API Documentation

    This document contains the API (Application Programming Interface) documentation for epydoc. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

    Object Documentation

    Each Package Documentation page contains:

    • A description of the package.
    • A list of the modules and sub-packages contained by the package.
    • A summary of the classes defined by the package.
    • A summary of the functions defined by the package.
    • A summary of the variables defined by the package.
    • A detailed description of each function defined by the package.
    • A detailed description of each variable defined by the package.

    Each Module Documentation page contains:

    • A description of the module.
    • A summary of the classes defined by the module.
    • A summary of the functions defined by the module.
    • A summary of the variables defined by the module.
    • A detailed description of each function defined by the module.
    • A detailed description of each variable defined by the module.

    Each Class Documentation page contains:

    • A class inheritance diagram.
    • A list of known subclasses.
    • A description of the class.
    • A summary of the methods defined by the class.
    • A summary of the instance variables defined by the class.
    • A summary of the class (static) variables defined by the class.
    • A detailed description of each method defined by the class.
    • A detailed description of each instance variable defined by the class.
    • A detailed description of each class (static) variable defined by the class.

    Project Documentation

    The Trees page contains the module and class hierarchies:

    • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
    • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

    The Index page contains indices of terms and identifiers:

    • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
    • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

    The Table of Contents

    The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

    Project
    Contents
    ...
    API
    Documentation
    Frame


    Module
    Contents
     
    ...
     

    The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

    The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

    The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

    The Navigation Bar

    A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

    Label Highlighted when... Links to...
    [Parent] (never highlighted) the parent of the current package
    [Package] viewing a package the package containing the current object
    [Module] viewing a module the module containing the current object
    [Class] viewing a class the class containing the current object
    [Trees] viewing the trees page the trees page
    [Index] viewing the index page the index page
    [Help] viewing the help page the help page

    The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

    A timestamp below the bottom navigation bar indicates when each page was last updated.

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc-pysrc.html0000644000175000017500000245022310750103050022257 0ustar pronovicpronovic epydoc.apidoc
    Package epydoc :: Module apidoc
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.apidoc

       1  # epydoc -- API Documentation Classes 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: apidoc.py 1675 2008-01-29 17:12:56Z edloper $ 
       8   
       9  """ 
      10  Classes for encoding API documentation about Python programs. 
      11  These classes are used as a common representation for combining 
      12  information derived from introspection and from parsing. 
      13   
      14  The API documentation for a Python program is encoded using a graph of 
      15  L{APIDoc} objects, each of which encodes information about a single 
      16  Python variable or value.  C{APIDoc} has two direct subclasses: 
      17  L{VariableDoc}, for documenting variables; and L{ValueDoc}, for 
      18  documenting values.  The C{ValueDoc} class is subclassed further, to 
      19  define the different pieces of information that should be recorded 
      20  about each value type: 
      21   
      22  G{classtree: APIDoc} 
      23   
      24  The distinction between variables and values is intentionally made 
      25  explicit.  This allows us to distinguish information about a variable 
      26  itself (such as whether it should be considered 'public' in its 
      27  containing namespace) from information about the value it contains 
      28  (such as what type the value has).  This distinction is also important 
      29  because several variables can contain the same value: each variable 
      30  should be described by a separate C{VariableDoc}; but we only need one 
      31  C{ValueDoc}, since they share a single value. 
      32   
      33  @todo: Add a cache to canonical name lookup? 
      34  """ 
      35  __docformat__ = 'epytext en' 
      36   
      37  ###################################################################### 
      38  ## Imports 
      39  ###################################################################### 
      40   
      41  import types, re, os.path, pickle 
      42  from epydoc import log 
      43  import epydoc 
      44  import __builtin__ 
      45  from epydoc.compat import * # Backwards compatibility 
      46  from epydoc.util import decode_with_backslashreplace, py_src_filename 
      47  import epydoc.markup.pyval_repr 
      48   
      49  ###################################################################### 
      50  # Dotted Names 
      51  ###################################################################### 
      52   
    
    53 -class DottedName:
    54 """ 55 A sequence of identifiers, separated by periods, used to name a 56 Python variable, value, or argument. The identifiers that make up 57 a dotted name can be accessed using the indexing operator: 58 59 >>> name = DottedName('epydoc', 'api_doc', 'DottedName') 60 >>> print name 61 epydoc.apidoc.DottedName 62 >>> name[1] 63 'api_doc' 64 """ 65 UNREACHABLE = "??" 66 _IDENTIFIER_RE = re.compile("""(?x) 67 (%s | # UNREACHABLE marker, or.. 68 (script-)? # Prefix: script (not a module) 69 \w+ # Identifier (yes, identifiers starting with a 70 # digit are allowed. See SF bug #1649347) 71 '?) # Suffix: submodule that is shadowed by a var 72 (-\d+)? # Suffix: unreachable vals with the same name 73 $""" 74 % re.escape(UNREACHABLE)) 75
    76 - class InvalidDottedName(ValueError):
    77 """ 78 An exception raised by the DottedName constructor when one of 79 its arguments is not a valid dotted name. 80 """
    81 82 _ok_identifiers = set() 83 """A cache of identifier strings that have been checked against 84 _IDENTIFIER_RE and found to be acceptable.""" 85
    86 - def __init__(self, *pieces, **options):
    87 """ 88 Construct a new dotted name from the given sequence of pieces, 89 each of which can be either a C{string} or a C{DottedName}. 90 Each piece is divided into a sequence of identifiers, and 91 these sequences are combined together (in order) to form the 92 identifier sequence for the new C{DottedName}. If a piece 93 contains a string, then it is divided into substrings by 94 splitting on periods, and each substring is checked to see if 95 it is a valid identifier. 96 97 As an optimization, C{pieces} may also contain a single tuple 98 of values. In that case, that tuple will be used as the 99 C{DottedName}'s identifiers; it will I{not} be checked to 100 see if it's valid. 101 102 @kwparam strict: if true, then raise an L{InvalidDottedName} 103 if the given name is invalid. 104 """ 105 if len(pieces) == 1 and isinstance(pieces[0], tuple): 106 self._identifiers = pieces[0] # Optimization 107 return 108 if len(pieces) == 0: 109 raise DottedName.InvalidDottedName('Empty DottedName') 110 self._identifiers = [] 111 for piece in pieces: 112 if isinstance(piece, DottedName): 113 self._identifiers += piece._identifiers 114 elif isinstance(piece, basestring): 115 for subpiece in piece.split('.'): 116 if piece not in self._ok_identifiers: 117 if not self._IDENTIFIER_RE.match(subpiece): 118 if options.get('strict'): 119 raise DottedName.InvalidDottedName( 120 'Bad identifier %r' % (piece,)) 121 else: 122 log.warning("Identifier %r looks suspicious; " 123 "using it anyway." % piece) 124 self._ok_identifiers.add(piece) 125 self._identifiers.append(subpiece) 126 else: 127 raise TypeError('Bad identifier %r: expected ' 128 'DottedName or str' % (piece,)) 129 self._identifiers = tuple(self._identifiers)
    130
    131 - def __repr__(self):
    132 idents = [`ident` for ident in self._identifiers] 133 return 'DottedName(' + ', '.join(idents) + ')'
    134
    135 - def __str__(self):
    136 """ 137 Return the dotted name as a string formed by joining its 138 identifiers with periods: 139 140 >>> print DottedName('epydoc', 'api_doc', DottedName') 141 epydoc.apidoc.DottedName 142 """ 143 return '.'.join(self._identifiers)
    144
    145 - def __add__(self, other):
    146 """ 147 Return a new C{DottedName} whose identifier sequence is formed 148 by adding C{other}'s identifier sequence to C{self}'s. 149 """ 150 if isinstance(other, (basestring, DottedName)): 151 return DottedName(self, other) 152 else: 153 return DottedName(self, *other)
    154
    155 - def __radd__(self, other):
    156 """ 157 Return a new C{DottedName} whose identifier sequence is formed 158 by adding C{self}'s identifier sequence to C{other}'s. 159 """ 160 if isinstance(other, (basestring, DottedName)): 161 return DottedName(other, self) 162 else: 163 return DottedName(*(list(other)+[self]))
    164
    165 - def __getitem__(self, i):
    166 """ 167 Return the C{i}th identifier in this C{DottedName}. If C{i} is 168 a non-empty slice, then return a C{DottedName} built from the 169 identifiers selected by the slice. If C{i} is an empty slice, 170 return an empty list (since empty C{DottedName}s are not valid). 171 """ 172 if isinstance(i, types.SliceType): 173 pieces = self._identifiers[i.start:i.stop] 174 if pieces: return DottedName(pieces) 175 else: return [] 176 else: 177 return self._identifiers[i]
    178
    179 - def __hash__(self):
    180 return hash(self._identifiers)
    181
    182 - def __cmp__(self, other):
    183 """ 184 Compare this dotted name to C{other}. Two dotted names are 185 considered equal if their identifier subsequences are equal. 186 Ordering between dotted names is lexicographic, in order of 187 identifier from left to right. 188 """ 189 if not isinstance(other, DottedName): 190 return -1 191 return cmp(self._identifiers, other._identifiers)
    192
    193 - def __len__(self):
    194 """ 195 Return the number of identifiers in this dotted name. 196 """ 197 return len(self._identifiers)
    198
    199 - def container(self):
    200 """ 201 Return the DottedName formed by removing the last identifier 202 from this dotted name's identifier sequence. If this dotted 203 name only has one name in its identifier sequence, return 204 C{None} instead. 205 """ 206 if len(self._identifiers) == 1: 207 return None 208 else: 209 return DottedName(*self._identifiers[:-1])
    210
    211 - def dominates(self, name, strict=False):
    212 """ 213 Return true if this dotted name is equal to a prefix of 214 C{name}. If C{strict} is true, then also require that 215 C{self!=name}. 216 217 >>> DottedName('a.b').dominates(DottedName('a.b.c.d')) 218 True 219 """ 220 len_self = len(self._identifiers) 221 len_name = len(name._identifiers) 222 223 if (len_self > len_name) or (strict and len_self == len_name): 224 return False 225 # The following is redundant (the first clause is implied by 226 # the second), but is done as an optimization. 227 return ((self._identifiers[0] == name._identifiers[0]) and 228 self._identifiers == name._identifiers[:len_self])
    229
    230 - def contextualize(self, context):
    231 """ 232 If C{self} and C{context} share a common ancestor, then return 233 a name for C{self}, relative to that ancestor. If they do not 234 share a common ancestor (or if C{context} is C{UNKNOWN}), then 235 simply return C{self}. 236 237 This is used to generate shorter versions of dotted names in 238 cases where users can infer the intended target from the 239 context. 240 241 @type context: L{DottedName} 242 @rtype: L{DottedName} 243 """ 244 if context is UNKNOWN or not context or len(self) <= 1: 245 return self 246 if self[0] == context[0]: 247 return self[1:].contextualize(context[1:]) 248 else: 249 return self 250 251 # Find the first index where self & context differ. 252 for i in range(min(len(context), len(self))): 253 if self._identifiers[i] != context._identifiers[i]: 254 first_difference = i 255 break 256 else: 257 first_difference = i+1 258 259 # Strip off anything before that index. 260 if first_difference == 0: 261 return self 262 elif first_difference == len(self): 263 return self[-1:] 264 else: 265 return self[first_difference:]
    266 267 ###################################################################### 268 # UNKNOWN Value 269 ###################################################################### 270
    271 -class _Sentinel:
    272 """ 273 A unique value that won't compare equal to any other value. This 274 class is used to create L{UNKNOWN}. 275 """
    276 - def __init__(self, name):
    277 self.name = name
    278 - def __repr__(self):
    279 return '<%s>' % self.name
    280 - def __nonzero__(self):
    281 raise ValueError('Sentinel value <%s> can not be used as a boolean' % 282 self.name)
    283 284 UNKNOWN = _Sentinel('UNKNOWN') 285 """A special value used to indicate that a given piece of 286 information about an object is unknown. This is used as the 287 default value for all instance variables.""" 288 289 ###################################################################### 290 # API Documentation Objects: Abstract Base Classes 291 ###################################################################### 292
    293 -class APIDoc(object):
    294 """ 295 API documentation information for a single element of a Python 296 program. C{APIDoc} itself is an abstract base class; subclasses 297 are used to specify what information should be recorded about each 298 type of program element. In particular, C{APIDoc} has two direct 299 subclasses, C{VariableDoc} for documenting variables and 300 C{ValueDoc} for documenting values; and the C{ValueDoc} class is 301 subclassed further for different value types. 302 303 Each C{APIDoc} subclass specifies the set of attributes that 304 should be used to record information about the corresponding 305 program element type. The default value for each attribute is 306 stored in the class; these default values can then be overridden 307 with instance variables. Most attributes use the special value 308 L{UNKNOWN} as their default value, to indicate that the correct 309 value for that attribute has not yet been determined. This makes 310 it easier to merge two C{APIDoc} objects that are documenting the 311 same element (in particular, to merge information about an element 312 that was derived from parsing with information that was derived 313 from introspection). 314 315 For all attributes with boolean values, use only the constants 316 C{True} and C{False} to designate true and false. In particular, 317 do I{not} use other values that evaluate as true or false, such as 318 C{2} or C{()}. This restriction makes it easier to handle 319 C{UNKNOWN} values. For example, to test if a boolean attribute is 320 C{True} or C{UNKNOWN}, use 'C{attrib in (True, UNKNOWN)}' or 321 'C{attrib is not False}'. 322 323 Two C{APIDoc} objects describing the same object can be X{merged}, 324 using the method L{merge_and_overwrite(other)}. After two 325 C{APIDoc}s are merged, any changes to one will be reflected in the 326 other. This is accomplished by setting the two C{APIDoc} objects 327 to use a shared instance dictionary. See the documentation for 328 L{merge_and_overwrite} for more information, and some important 329 caveats about hashing. 330 """ 331 #{ Docstrings 332 docstring = UNKNOWN 333 """@ivar: The documented item's docstring. 334 @type: C{string} or C{None}""" 335 336 docstring_lineno = UNKNOWN 337 """@ivar: The line number on which the documented item's docstring 338 begins. 339 @type: C{int}""" 340 #} end of "docstrings" group 341 342 #{ Information Extracted from Docstrings 343 descr = UNKNOWN 344 """@ivar: A description of the documented item, extracted from its 345 docstring. 346 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 347 348 summary = UNKNOWN 349 """@ivar: A summary description of the documented item, extracted from 350 its docstring. 351 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 352 353 other_docs = UNKNOWN 354 """@ivar: A flag indicating if the entire L{docstring} body (except tags 355 if any) is entirely included in the L{summary}. 356 @type: C{bool}""" 357 358 metadata = UNKNOWN 359 """@ivar: Metadata about the documented item, extracted from fields in 360 its docstring. I{Currently} this is encoded as a list of tuples 361 C{(field, arg, descr)}. But that may change. 362 @type: C{(str, str, L{ParsedDocstring<markup.ParsedDocstring>})}""" 363 364 extra_docstring_fields = UNKNOWN 365 """@ivar: A list of new docstring fields tags that are defined by the 366 documented item's docstring. These new field tags can be used by 367 this item or by any item it contains. 368 @type: L{DocstringField <epydoc.docstringparser.DocstringField>}""" 369 #} end of "information extracted from docstrings" group 370 371 #{ Source Information 372 docs_extracted_by = UNKNOWN # 'parser' or 'introspecter' or 'both' 373 """@ivar: Information about where the information contained by this 374 C{APIDoc} came from. Can be one of C{'parser'}, 375 C{'introspector'}, or C{'both'}. 376 @type: C{str}""" 377 #} end of "source information" group 378
    379 - def __init__(self, **kwargs):
    380 """ 381 Construct a new C{APIDoc} object. Keyword arguments may be 382 used to initialize the new C{APIDoc}'s attributes. 383 384 @raise TypeError: If a keyword argument is specified that does 385 not correspond to a valid attribute for this (sub)class of 386 C{APIDoc}. 387 """ 388 if epydoc.DEBUG: 389 for key in kwargs: 390 if key[0] != '_' and not hasattr(self.__class__, key): 391 raise TypeError('%s got unexpected arg %r' % 392 (self.__class__.__name__, key)) 393 self.__dict__.update(kwargs)
    394
    395 - def _debug_setattr(self, attr, val):
    396 """ 397 Modify an C{APIDoc}'s attribute. This is used when 398 L{epydoc.DEBUG} is true, to make sure we don't accidentally 399 set any inappropriate attributes on C{APIDoc} objects. 400 401 @raise AttributeError: If C{attr} is not a valid attribute for 402 this (sub)class of C{APIDoc}. (C{attr} is considered a 403 valid attribute iff C{self.__class__} defines an attribute 404 with that name.) 405 """ 406 # Don't intercept special assignments like __class__, or 407 # assignments to private variables. 408 if attr.startswith('_'): 409 return object.__setattr__(self, attr, val) 410 if not hasattr(self, attr): 411 raise AttributeError('%s does not define attribute %r' % 412 (self.__class__.__name__, attr)) 413 self.__dict__[attr] = val
    414 415 if epydoc.DEBUG: 416 __setattr__ = _debug_setattr 417
    418 - def __repr__(self):
    419 return '<%s>' % self.__class__.__name__
    420
    421 - def pp(self, doublespace=0, depth=5, exclude=(), include=()):
    422 """ 423 Return a pretty-printed string representation for the 424 information contained in this C{APIDoc}. 425 """ 426 return pp_apidoc(self, doublespace, depth, exclude, include)
    427 __str__ = pp 428
    429 - def specialize_to(self, cls):
    430 """ 431 Change C{self}'s class to C{cls}. C{cls} must be a subclass 432 of C{self}'s current class. For example, if a generic 433 C{ValueDoc} was created for a value, and it is determined that 434 the value is a routine, you can update its class with: 435 436 >>> valdoc.specialize_to(RoutineDoc) 437 """ 438 if not issubclass(cls, self.__class__): 439 raise ValueError('Can not specialize to %r' % cls) 440 # Update the class. 441 self.__class__ = cls 442 # Update the class of any other apidoc's in the mergeset. 443 if self.__mergeset is not None: 444 for apidoc in self.__mergeset: 445 apidoc.__class__ = cls 446 # Re-initialize self, in case the subclass constructor does 447 # any special processing on its arguments. 448 self.__init__(**self.__dict__)
    449 450 __has_been_hashed = False 451 """True iff L{self.__hash__()} has ever been called.""" 452
    453 - def __hash__(self):
    454 self.__has_been_hashed = True 455 return id(self.__dict__)
    456
    457 - def __cmp__(self, other):
    458 if not isinstance(other, APIDoc): return -1 459 if self.__dict__ is other.__dict__: return 0 460 name_cmp = cmp(self.canonical_name, other.canonical_name) 461 if name_cmp == 0: return -1 462 else: return name_cmp
    463
    464 - def is_detailed(self):
    465 """ 466 Does this object deserve a box with extra details? 467 468 @return: True if the object needs extra details, else False. 469 @rtype: C{bool} 470 """ 471 if self.other_docs is True: 472 return True 473 474 if self.metadata is not UNKNOWN: 475 return bool(self.metadata)
    476 477 __mergeset = None 478 """The set of all C{APIDoc} objects that have been merged with 479 this C{APIDoc} (using L{merge_and_overwrite()}). Each C{APIDoc} 480 in this set shares a common instance dictionary (C{__dict__}).""" 481
    482 - def merge_and_overwrite(self, other, ignore_hash_conflict=False):
    483 """ 484 Combine C{self} and C{other} into a X{merged object}, such 485 that any changes made to one will affect the other. Any 486 attributes that C{other} had before merging will be discarded. 487 This is accomplished by copying C{self.__dict__} over 488 C{other.__dict__} and C{self.__class__} over C{other.__class__}. 489 490 Care must be taken with this method, since it modifies the 491 hash value of C{other}. To help avoid the problems that this 492 can cause, C{merge_and_overwrite} will raise an exception if 493 C{other} has ever been hashed, unless C{ignore_hash_conflict} 494 is True. Note that adding C{other} to a dictionary, set, or 495 similar data structure will implicitly cause it to be hashed. 496 If you do set C{ignore_hash_conflict} to True, then any 497 existing data structures that rely on C{other}'s hash staying 498 constant may become corrupted. 499 500 @return: C{self} 501 @raise ValueError: If C{other} has ever been hashed. 502 """ 503 # If we're already merged, then there's nothing to do. 504 if (self.__dict__ is other.__dict__ and 505 self.__class__ is other.__class__): return self 506 507 if other.__has_been_hashed and not ignore_hash_conflict: 508 raise ValueError("%r has already been hashed! Merging it " 509 "would cause its has value to change." % other) 510 511 # If other was itself already merged with anything, 512 # then we need to merge those too. 513 a,b = (self.__mergeset, other.__mergeset) 514 mergeset = (self.__mergeset or [self]) + (other.__mergeset or [other]) 515 other.__dict__.clear() 516 for apidoc in mergeset: 517 #if apidoc is self: pass 518 apidoc.__class__ = self.__class__ 519 apidoc.__dict__ = self.__dict__ 520 self.__mergeset = mergeset 521 # Sanity chacks. 522 assert self in mergeset and other in mergeset 523 for apidoc in mergeset: 524 assert apidoc.__dict__ is self.__dict__ 525 # Return self. 526 return self
    527
    551
    552 -def reachable_valdocs(root, **filters):
    553 """ 554 Return a list of all C{ValueDoc}s that can be reached, directly or 555 indirectly from the given root list of C{ValueDoc}s. 556 557 @param filters: A set of filters that can be used to prevent 558 C{reachable_valdocs} from following specific link types when 559 looking for C{ValueDoc}s that can be reached from the root 560 set. See C{APIDoc.apidoc_links} for a more complete 561 description. 562 """ 563 apidoc_queue = list(root) 564 val_set = set() 565 var_set = set() 566 while apidoc_queue: 567 api_doc = apidoc_queue.pop() 568 if isinstance(api_doc, ValueDoc): 569 val_set.add(api_doc) 570 else: 571 var_set.add(api_doc) 572 apidoc_queue.extend([v for v in api_doc.apidoc_links(**filters) 573 if v not in val_set and v not in var_set]) 574 return val_set
    575 576 ###################################################################### 577 # Variable Documentation Objects 578 ###################################################################### 579
    580 -class VariableDoc(APIDoc):
    581 """ 582 API documentation information about a single Python variable. 583 584 @note: The only time a C{VariableDoc} will have its own docstring 585 is if that variable was created using an assignment statement, and 586 that assignment statement had a docstring-comment or was followed 587 by a pseudo-docstring. 588 """ 589 #{ Basic Variable Information 590 name = UNKNOWN 591 """@ivar: The name of this variable in its containing namespace. 592 @type: C{str}""" 593 594 container = UNKNOWN 595 """@ivar: API documentation for the namespace that contains this 596 variable. 597 @type: L{ValueDoc}""" 598 599 canonical_name = UNKNOWN 600 """@ivar: A dotted name that serves as a unique identifier for 601 this C{VariableDoc}. It should be formed by concatenating 602 the C{VariableDoc}'s C{container} with its C{name}. 603 @type: L{DottedName}""" 604 605 value = UNKNOWN 606 """@ivar: The API documentation for this variable's value. 607 @type: L{ValueDoc}""" 608 #} 609 610 #{ Information Extracted from Docstrings 611 type_descr = UNKNOWN 612 """@ivar: A description of the variable's expected type, extracted from 613 its docstring. 614 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 615 #} end of "information extracted from docstrings" group 616 617 #{ Information about Imported Variables 618 imported_from = UNKNOWN 619 """@ivar: The fully qualified dotted name of the variable that this 620 variable's value was imported from. This attribute should only 621 be defined if C{is_instvar} is true. 622 @type: L{DottedName}""" 623 624 is_imported = UNKNOWN 625 """@ivar: Was this variable's value imported from another module? 626 (Exception: variables that are explicitly included in __all__ have 627 C{is_imported} set to C{False}, even if they are in fact 628 imported.) 629 @type: C{bool}""" 630 #} end of "information about imported variables" group 631 632 #{ Information about Variables in Classes 633 is_instvar = UNKNOWN 634 """@ivar: If true, then this variable is an instance variable; if false, 635 then this variable is a class variable. This attribute should 636 only be defined if the containing namespace is a class 637 @type: C{bool}""" 638 639 overrides = UNKNOWN # [XXX] rename -- don't use a verb. 640 """@ivar: The API documentation for the variable that is overridden by 641 this variable. This attribute should only be defined if the 642 containing namespace is a class. 643 @type: L{VariableDoc}""" 644 #} end of "information about variables in classes" group 645 646 #{ Flags 647 is_alias = UNKNOWN 648 """@ivar: Is this variable an alias for another variable with the same 649 value? If so, then this variable will be dispreferred when 650 assigning canonical names. 651 @type: C{bool}""" 652 653 is_public = UNKNOWN 654 """@ivar: Is this variable part of its container's public API? 655 @type: C{bool}""" 656 #} end of "flags" group 657
    658 - def __init__(self, **kwargs):
    659 APIDoc.__init__(self, **kwargs) 660 if self.is_public is UNKNOWN and self.name is not UNKNOWN: 661 self.is_public = (not self.name.startswith('_') or 662 self.name.endswith('_'))
    663
    664 - def __repr__(self):
    665 if self.canonical_name is not UNKNOWN: 666 return '<%s %s>' % (self.__class__.__name__, self.canonical_name) 667 if self.name is not UNKNOWN: 668 return '<%s %s>' % (self.__class__.__name__, self.name) 669 else: 670 return '<%s>' % self.__class__.__name__
    671
    672 - def _get_defining_module(self):
    673 if self.container is UNKNOWN: 674 return UNKNOWN 675 return self.container.defining_module
    676 defining_module = property(_get_defining_module, doc=""" 677 A read-only property that can be used to get the variable's 678 defining module. This is defined as the defining module 679 of the variable's container.""") 680 692
    693 - def is_detailed(self):
    694 pval = super(VariableDoc, self).is_detailed() 695 if pval or self.value in (None, UNKNOWN): 696 return pval 697 698 if (self.overrides not in (None, UNKNOWN) and 699 isinstance(self.value, RoutineDoc)): 700 return True 701 702 if isinstance(self.value, GenericValueDoc): 703 # [XX] This is a little hackish -- we assume that the 704 # summary lines will have SUMMARY_REPR_LINELEN chars, 705 # that len(name) of those will be taken up by the name, 706 # and that 3 of those will be taken up by " = " between 707 # the name & val. Note that if any docwriter uses a 708 # different formula for maxlen for this, then it will 709 # not get the right value for is_detailed(). 710 maxlen = self.value.SUMMARY_REPR_LINELEN-3-len(self.name) 711 return (not self.value.summary_pyval_repr(maxlen).is_complete) 712 else: 713 return self.value.is_detailed()
    714 715 ###################################################################### 716 # Value Documentation Objects 717 ###################################################################### 718
    719 -class ValueDoc(APIDoc):
    720 """ 721 API documentation information about a single Python value. 722 """ 723 canonical_name = UNKNOWN 724 """@ivar: A dotted name that serves as a unique identifier for 725 this C{ValueDoc}'s value. If the value can be reached using a 726 single sequence of identifiers (given the appropriate imports), 727 then that sequence of identifiers is used as its canonical name. 728 If the value can be reached by multiple sequences of identifiers 729 (i.e., if it has multiple aliases), then one of those sequences of 730 identifiers is used. If the value cannot be reached by any 731 sequence of identifiers (e.g., if it was used as a base class but 732 then its variable was deleted), then its canonical name will start 733 with C{'??'}. If necessary, a dash followed by a number will be 734 appended to the end of a non-reachable identifier to make its 735 canonical name unique. 736 737 When possible, canonical names are chosen when new C{ValueDoc}s 738 are created. However, this is sometimes not possible. If a 739 canonical name can not be chosen when the C{ValueDoc} is created, 740 then one will be assigned by L{assign_canonical_names() 741 <docbuilder.assign_canonical_names>}. 742 743 @type: L{DottedName}""" 744 745 #{ Value Representation 746 pyval = UNKNOWN 747 """@ivar: A pointer to the actual Python object described by this 748 C{ValueDoc}. This is used to display the value (e.g., when 749 describing a variable.) Use L{pyval_repr()} to generate a 750 plaintext string representation of this value. 751 @type: Python object""" 752 753 parse_repr = UNKNOWN 754 """@ivar: A text representation of this value, extracted from 755 parsing its source code. This representation may not accurately 756 reflect the actual value (e.g., if the value was modified after 757 the initial assignment). 758 @type: C{unicode}""" 759 760 REPR_MAXLINES = 5 761 """@cvar: The maximum number of lines of text that should be 762 generated by L{pyval_repr()}. If the string representation does 763 not fit in this number of lines, an ellpsis marker (...) will 764 be placed at the end of the formatted representation.""" 765 766 REPR_LINELEN = 75 767 """@cvar: The maximum number of characters for lines of text that 768 should be generated by L{pyval_repr()}. Any lines that exceed 769 this number of characters will be line-wrappped; The S{crarr} 770 symbol will be used to indicate that the line was wrapped.""" 771 772 SUMMARY_REPR_LINELEN = 75 773 """@cvar: The maximum number of characters for the single-line 774 text representation generated by L{summary_pyval_repr()}. If 775 the value's representation does not fit in this number of 776 characters, an ellipsis marker (...) will be placed at the end 777 of the formatted representation.""" 778 779 REPR_MIN_SCORE = 0 780 """@cvar: The minimum score that a value representation based on 781 L{pyval} should have in order to be used instead of L{parse_repr} 782 as the canonical representation for this C{ValueDoc}'s value. 783 @see: L{epydoc.markup.pyval_repr}""" 784 #} end of "value representation" group 785 786 #{ Context 787 defining_module = UNKNOWN 788 """@ivar: The documentation for the module that defines this 789 value. This is used, e.g., to lookup the appropriate markup 790 language for docstrings. For a C{ModuleDoc}, 791 C{defining_module} should be C{self}. 792 @type: L{ModuleDoc}""" 793 #} end of "context group" 794 795 #{ Information about Imported Variables 796 proxy_for = None # [xx] in progress. 797 """@ivar: If C{proxy_for} is not None, then this value was 798 imported from another file. C{proxy_for} is the dotted name of 799 the variable that this value was imported from. If that 800 variable is documented, then its C{value} may contain more 801 complete API documentation about this value. The C{proxy_for} 802 attribute is used by the source code parser to link imported 803 values to their source values (in particular, for base 804 classes). When possible, these proxy C{ValueDoc}s are replaced 805 by the imported value's C{ValueDoc} by 806 L{link_imports()<docbuilder.link_imports>}. 807 @type: L{DottedName}""" 808 #} end of "information about imported variables" group 809 810 #: @ivar: 811 #: This is currently used to extract values from __all__, etc, in 812 #: the docparser module; maybe I should specialize 813 #: process_assignment and extract it there? Although, for __all__, 814 #: it's not clear where I'd put the value, since I just use it to 815 #: set private/public/imported attribs on other vars (that might not 816 #: exist yet at the time.) 817 toktree = UNKNOWN 818
    819 - def __repr__(self):
    820 if self.canonical_name is not UNKNOWN: 821 return '<%s %s>' % (self.__class__.__name__, self.canonical_name) 822 else: 823 return '<%s %s>' % (self.__class__.__name__, 824 self.summary_pyval_repr().to_plaintext(None))
    825
    826 - def __setstate__(self, state):
    827 self.__dict__ = state
    828
    829 - def __getstate__(self):
    830 """ 831 State serializer for the pickle module. This is necessary 832 because sometimes the C{pyval} attribute contains an 833 un-pickleable value. 834 """ 835 # Construct our pickled dictionary. Maintain this dictionary 836 # as a private attribute, so we can reuse it later, since 837 # merged objects need to share a single dictionary. 838 if not hasattr(self, '_ValueDoc__pickle_state'): 839 # Make sure __pyval_repr & __summary_pyval_repr are cached: 840 self.pyval_repr(), self.summary_pyval_repr() 841 # Construct the dictionary; leave out 'pyval'. 842 self.__pickle_state = self.__dict__.copy() 843 self.__pickle_state['pyval'] = UNKNOWN 844 845 if not isinstance(self, GenericValueDoc): 846 assert self.__pickle_state != {} 847 # Return the pickle state. 848 return self.__pickle_state
    849 850 #{ Value Representation
    851 - def pyval_repr(self):
    852 """ 853 Return a formatted representation of the Python object 854 described by this C{ValueDoc}. This representation may 855 include data from introspection or parsing, and is authorative 856 as 'the best way to represent a Python value.' Any lines that 857 go beyond L{REPR_LINELEN} characters will be wrapped; and if 858 the representation as a whole takes more than L{REPR_MAXLINES} 859 lines, then it will be truncated (with an ellipsis marker). 860 This function will never return L{UNKNOWN} or C{None}. 861 862 @rtype: L{ColorizedPyvalRepr} 863 """ 864 # Use self.__pyval_repr to cache the result. 865 if not hasattr(self, '_ValueDoc__pyval_repr'): 866 self.__pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( 867 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 868 self.REPR_LINELEN, self.REPR_MAXLINES, linebreakok=True) 869 return self.__pyval_repr
    870
    871 - def summary_pyval_repr(self, max_len=None):
    872 """ 873 Return a single-line formatted representation of the Python 874 object described by this C{ValueDoc}. This representation may 875 include data from introspection or parsing, and is authorative 876 as 'the best way to summarize a Python value.' If the 877 representation takes more then L{SUMMARY_REPR_LINELEN} 878 characters, then it will be truncated (with an ellipsis 879 marker). This function will never return L{UNKNOWN} or 880 C{None}. 881 882 @rtype: L{ColorizedPyvalRepr} 883 """ 884 # If max_len is specified, then do *not* cache the result. 885 if max_len is not None: 886 return epydoc.markup.pyval_repr.colorize_pyval( 887 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 888 max_len, maxlines=1, linebreakok=False) 889 890 # Use self.__summary_pyval_repr to cache the result. 891 if not hasattr(self, '_ValueDoc__summary_pyval_repr'): 892 self.__summary_pyval_repr = epydoc.markup.pyval_repr.colorize_pyval( 893 self.pyval, self.parse_repr, self.REPR_MIN_SCORE, 894 self.SUMMARY_REPR_LINELEN, maxlines=1, linebreakok=False) 895 return self.__summary_pyval_repr
    896 #} end of "value representation" group 897
    900
    901 -class GenericValueDoc(ValueDoc):
    902 """ 903 API documentation about a 'generic' value, i.e., one that does not 904 have its own docstring or any information other than its value and 905 parse representation. C{GenericValueDoc}s do not get assigned 906 cannonical names. 907 """ 908 canonical_name = None 909
    910 - def is_detailed(self):
    911 return (not self.summary_pyval_repr().is_complete)
    912
    913 -class NamespaceDoc(ValueDoc):
    914 """ 915 API documentation information about a singe Python namespace 916 value. (I.e., a module or a class). 917 """ 918 #{ Information about Variables 919 variables = UNKNOWN 920 """@ivar: The contents of the namespace, encoded as a 921 dictionary mapping from identifiers to C{VariableDoc}s. This 922 dictionary contains all names defined by the namespace, 923 including imported variables, aliased variables, and variables 924 inherited from base classes (once L{inherit_docs() 925 <epydoc.docbuilder.inherit_docs>} has added them). 926 @type: C{dict} from C{string} to L{VariableDoc}""" 927 sorted_variables = UNKNOWN 928 """@ivar: A list of all variables defined by this 929 namespace, in sorted order. The elements of this list should 930 exactly match the values of L{variables}. The sort order for 931 this list is defined as follows: 932 - Any variables listed in a C{@sort} docstring field are 933 listed in the order given by that field. 934 - These are followed by any variables that were found while 935 parsing the source code, in the order in which they were 936 defined in the source file. 937 - Finally, any remaining variables are listed in 938 alphabetical order. 939 @type: C{list} of L{VariableDoc}""" 940 sort_spec = UNKNOWN 941 """@ivar: The order in which variables should be listed, 942 encoded as a list of names. Any variables whose names are not 943 included in this list should be listed alphabetically, 944 following the variables that are included. 945 @type: C{list} of C{str}""" 946 group_specs = UNKNOWN 947 """@ivar: The groups that are defined by this namespace's 948 docstrings. C{group_specs} is encoded as an ordered list of 949 tuples C{(group_name, elt_names)}, where C{group_name} is the 950 951 name of a group and C{elt_names} is a list of element names in 952 that group. (An element can be a variable or a submodule.) A 953 '*' in an element name will match any string of characters. 954 @type: C{list} of C{(str,list)}""" 955 variable_groups = UNKNOWN 956 """@ivar: A dictionary specifying what group each 957 variable belongs to. The keys of the dictionary are group 958 names, and the values are lists of C{VariableDoc}s. The order 959 that groups should be listed in should be taken from 960 L{group_specs}. 961 @type: C{dict} from C{str} to C{list} of L{VariableDoc}""" 962 #} end of group "information about variables" 963
    964 - def __init__(self, **kwargs):
    965 kwargs.setdefault('variables', {}) 966 APIDoc.__init__(self, **kwargs) 967 assert self.variables is not UNKNOWN
    968
    969 - def is_detailed(self):
    970 return True
    971 990
    991 - def init_sorted_variables(self):
    992 """ 993 Initialize the L{sorted_variables} attribute, based on the 994 L{variables} and L{sort_spec} attributes. This should usually 995 be called after all variables have been added to C{variables} 996 (including any inherited variables for classes). 997 """ 998 unsorted = self.variables.copy() 999 self.sorted_variables = [] 1000 1001 # Add any variables that are listed in sort_spec 1002 if self.sort_spec is not UNKNOWN: 1003 unused_idents = set(self.sort_spec) 1004 for ident in self.sort_spec: 1005 if ident in unsorted: 1006 self.sorted_variables.append(unsorted.pop(ident)) 1007 unused_idents.discard(ident) 1008 elif '*' in ident: 1009 regexp = re.compile('^%s$' % ident.replace('*', '(.*)')) 1010 # sort within matching group? 1011 for name, var_doc in unsorted.items(): 1012 if regexp.match(name): 1013 self.sorted_variables.append(unsorted.pop(name)) 1014 unused_idents.discard(ident) 1015 for ident in unused_idents: 1016 if ident not in ['__all__', '__docformat__', '__path__']: 1017 log.warning("@sort: %s.%s not found" % 1018 (self.canonical_name, ident)) 1019 1020 1021 # Add any remaining variables in alphabetical order. 1022 var_docs = unsorted.items() 1023 var_docs.sort() 1024 for name, var_doc in var_docs: 1025 self.sorted_variables.append(var_doc)
    1026
    1027 - def init_variable_groups(self):
    1028 """ 1029 Initialize the L{variable_groups} attribute, based on the 1030 L{sorted_variables} and L{group_specs} attributes. 1031 """ 1032 if self.sorted_variables is UNKNOWN: 1033 self.init_sorted_variables() 1034 assert len(self.sorted_variables) == len(self.variables) 1035 1036 elts = [(v.name, v) for v in self.sorted_variables] 1037 self._unused_groups = dict([(n,set(i)) for (n,i) in self.group_specs]) 1038 self.variable_groups = self._init_grouping(elts)
    1039
    1040 - def group_names(self):
    1041 """ 1042 Return a list of the group names defined by this namespace, in 1043 the order in which they should be listed, with no duplicates. 1044 """ 1045 name_list = [''] 1046 name_set = set() 1047 for name, spec in self.group_specs: 1048 if name not in name_set: 1049 name_set.add(name) 1050 name_list.append(name) 1051 return name_list
    1052
    1053 - def _init_grouping(self, elts):
    1054 """ 1055 Divide a given a list of APIDoc objects into groups, as 1056 specified by L{self.group_specs}. 1057 1058 @param elts: A list of tuples C{(name, apidoc)}. 1059 1060 @return: A list of tuples C{(groupname, elts)}, where 1061 C{groupname} is the name of a group and C{elts} is a list of 1062 C{APIDoc}s in that group. The first tuple has name C{''}, and 1063 is used for ungrouped elements. The remaining tuples are 1064 listed in the order that they appear in C{self.group_specs}. 1065 Within each tuple, the elements are listed in the order that 1066 they appear in C{api_docs}. 1067 """ 1068 # Make the common case fast. 1069 if len(self.group_specs) == 0: 1070 return {'': [elt[1] for elt in elts]} 1071 1072 ungrouped = set([elt_doc for (elt_name, elt_doc) in elts]) 1073 1074 ungrouped = dict(elts) 1075 groups = {} 1076 for elt_name, elt_doc in elts: 1077 for (group_name, idents) in self.group_specs: 1078 group = groups.setdefault(group_name, []) 1079 unused_groups = self._unused_groups[group_name] 1080 for ident in idents: 1081 if re.match('^%s$' % ident.replace('*', '(.*)'), elt_name): 1082 unused_groups.discard(ident) 1083 if elt_name in ungrouped: 1084 group.append(ungrouped.pop(elt_name)) 1085 else: 1086 log.warning("%s.%s in multiple groups" % 1087 (self.canonical_name, elt_name)) 1088 1089 # Convert ungrouped from an unordered set to an ordered list. 1090 groups[''] = [elt_doc for (elt_name, elt_doc) in elts 1091 if elt_name in ungrouped] 1092 return groups
    1093
    1094 - def report_unused_groups(self):
    1095 """ 1096 Issue a warning for any @group items that were not used by 1097 L{_init_grouping()}. 1098 """ 1099 for (group, unused_idents) in self._unused_groups.items(): 1100 for ident in unused_idents: 1101 log.warning("@group %s: %s.%s not found" % 1102 (group, self.canonical_name, ident))
    1103
    1104 -class ModuleDoc(NamespaceDoc):
    1105 """ 1106 API documentation information about a single module. 1107 """ 1108 #{ Information about the Module 1109 filename = UNKNOWN 1110 """@ivar: The name of the file that defines the module. 1111 @type: C{string}""" 1112 docformat = UNKNOWN 1113 """@ivar: The markup language used by docstrings in this module. 1114 @type: C{string}""" 1115 #{ Information about Submodules 1116 submodules = UNKNOWN 1117 """@ivar: Modules contained by this module (if this module 1118 is a package). (Note: on rare occasions, a module may have a 1119 submodule that is shadowed by a variable with the same name.) 1120 @type: C{list} of L{ModuleDoc}""" 1121 submodule_groups = UNKNOWN 1122 """@ivar: A dictionary specifying what group each 1123 submodule belongs to. The keys of the dictionary are group 1124 names, and the values are lists of C{ModuleDoc}s. The order 1125 that groups should be listed in should be taken from 1126 L{group_specs}. 1127 @type: C{dict} from C{str} to C{list} of L{ModuleDoc}""" 1128 #{ Information about Packages 1129 package = UNKNOWN 1130 """@ivar: API documentation for the module's containing package. 1131 @type: L{ModuleDoc}""" 1132 is_package = UNKNOWN 1133 """@ivar: True if this C{ModuleDoc} describes a package. 1134 @type: C{bool}""" 1135 path = UNKNOWN 1136 """@ivar: If this C{ModuleDoc} describes a package, then C{path} 1137 contains a list of directories that constitute its path (i.e., 1138 the value of its C{__path__} variable). 1139 @type: C{list} of C{str}""" 1140 #{ Information about Imported Variables 1141 imports = UNKNOWN 1142 """@ivar: A list of the source names of variables imported into 1143 this module. This is used to construct import graphs. 1144 @type: C{list} of L{DottedName}""" 1145 #} 1146 1156
    1157 - def init_submodule_groups(self):
    1158 """ 1159 Initialize the L{submodule_groups} attribute, based on the 1160 L{submodules} and L{group_specs} attributes. 1161 """ 1162 if self.submodules in (None, UNKNOWN): 1163 return 1164 self.submodules = sorted(self.submodules, 1165 key=lambda m:m.canonical_name) 1166 elts = [(m.canonical_name[-1], m) for m in self.submodules] 1167 self.submodule_groups = self._init_grouping(elts)
    1168
    1169 - def select_variables(self, group=None, value_type=None, public=None, 1170 imported=None, detailed=None):
    1171 """ 1172 Return a specified subset of this module's L{sorted_variables} 1173 list. If C{value_type} is given, then only return variables 1174 whose values have the specified type. If C{group} is given, 1175 then only return variables that belong to the specified group. 1176 1177 @require: The L{sorted_variables}, L{variable_groups}, and 1178 L{submodule_groups} attributes must be initialized before 1179 this method can be used. See L{init_sorted_variables()}, 1180 L{init_variable_groups()}, and L{init_submodule_groups()}. 1181 1182 @param value_type: A string specifying the value type for 1183 which variables should be returned. Valid values are: 1184 - 'class' - variables whose values are classes or types. 1185 - 'function' - variables whose values are functions. 1186 - 'other' - variables whose values are not classes, 1187 exceptions, types, or functions. 1188 @type value_type: C{string} 1189 1190 @param group: The name of the group for which variables should 1191 be returned. A complete list of the groups defined by 1192 this C{ModuleDoc} is available in the L{group_names} 1193 instance variable. The first element of this list is 1194 always the special group name C{''}, which is used for 1195 variables that do not belong to any group. 1196 @type group: C{string} 1197 1198 @param detailed: If True (False), return only the variables 1199 deserving (not deserving) a detailed informative box. 1200 If C{None}, don't care. 1201 @type detailed: C{bool} 1202 """ 1203 if (self.sorted_variables is UNKNOWN or 1204 self.variable_groups is UNKNOWN): 1205 raise ValueError('sorted_variables and variable_groups ' 1206 'must be initialized first.') 1207 1208 if group is None: var_list = self.sorted_variables 1209 else: 1210 var_list = self.variable_groups.get(group, self.sorted_variables) 1211 1212 # Public/private filter (Count UNKNOWN as public) 1213 if public is True: 1214 var_list = [v for v in var_list if v.is_public is not False] 1215 elif public is False: 1216 var_list = [v for v in var_list if v.is_public is False] 1217 1218 # Imported filter (Count UNKNOWN as non-imported) 1219 if imported is True: 1220 var_list = [v for v in var_list if v.is_imported is True] 1221 elif imported is False: 1222 var_list = [v for v in var_list if v.is_imported is not True] 1223 1224 # Detailed filter 1225 if detailed is True: 1226 var_list = [v for v in var_list if v.is_detailed() is True] 1227 elif detailed is False: 1228 var_list = [v for v in var_list if v.is_detailed() is not True] 1229 1230 # [xx] Modules are not currently included in any of these 1231 # value types. 1232 if value_type is None: 1233 return var_list 1234 elif value_type == 'class': 1235 return [var_doc for var_doc in var_list 1236 if (isinstance(var_doc.value, ClassDoc))] 1237 elif value_type == 'function': 1238 return [var_doc for var_doc in var_list 1239 if isinstance(var_doc.value, RoutineDoc)] 1240 elif value_type == 'other': 1241 return [var_doc for var_doc in var_list 1242 if not isinstance(var_doc.value, 1243 (ClassDoc, RoutineDoc, ModuleDoc))] 1244 else: 1245 raise ValueError('Bad value type %r' % value_type)
    1246
    1247 -class ClassDoc(NamespaceDoc):
    1248 """ 1249 API documentation information about a single class. 1250 """ 1251 #{ Information about Base Classes 1252 bases = UNKNOWN 1253 """@ivar: API documentation for the class's base classes. 1254 @type: C{list} of L{ClassDoc}""" 1255 #{ Information about Subclasses 1256 subclasses = UNKNOWN 1257 """@ivar: API documentation for the class's known subclasses. 1258 @type: C{list} of L{ClassDoc}""" 1259 #} 1260 1270
    1271 - def is_type(self):
    1272 if self.canonical_name == DottedName('type'): return True 1273 if self.bases is UNKNOWN: return False 1274 for base in self.bases: 1275 if isinstance(base, ClassDoc) and base.is_type(): 1276 return True 1277 return False
    1278
    1279 - def is_exception(self):
    1280 if self.canonical_name == DottedName('Exception'): return True 1281 if self.bases is UNKNOWN: return False 1282 for base in self.bases: 1283 if isinstance(base, ClassDoc) and base.is_exception(): 1284 return True 1285 return False
    1286
    1287 - def is_newstyle_class(self):
    1288 if self.canonical_name == DottedName('object'): return True 1289 if self.bases is UNKNOWN: return False 1290 for base in self.bases: 1291 if isinstance(base, ClassDoc) and base.is_newstyle_class(): 1292 return True 1293 return False
    1294
    1295 - def mro(self, warn_about_bad_bases=False):
    1296 if self.is_newstyle_class(): 1297 return self._c3_mro(warn_about_bad_bases) 1298 else: 1299 return self._dfs_bases([], set(), warn_about_bad_bases)
    1300
    1301 - def _dfs_bases(self, mro, seen, warn_about_bad_bases):
    1302 if self in seen: return mro 1303 mro.append(self) 1304 seen.add(self) 1305 if self.bases is not UNKNOWN: 1306 for base in self.bases: 1307 if isinstance(base, ClassDoc) and base.proxy_for is None: 1308 base._dfs_bases(mro, seen, warn_about_bad_bases) 1309 elif warn_about_bad_bases: 1310 self._report_bad_base(base) 1311 return mro
    1312
    1313 - def _c3_mro(self, warn_about_bad_bases):
    1314 """ 1315 Compute the class precedence list (mro) according to C3. 1316 @seealso: U{http://www.python.org/2.3/mro.html} 1317 """ 1318 bases = [base for base in self.bases if isinstance(base, ClassDoc)] 1319 if len(bases) != len(self.bases) and warn_about_bad_bases: 1320 for base in self.bases: 1321 if (not isinstance(base, ClassDoc) or 1322 base.proxy_for is not None): 1323 self._report_bad_base(base) 1324 w = [warn_about_bad_bases]*len(bases) 1325 return self._c3_merge([[self]] + map(ClassDoc._c3_mro, bases, w) + 1326 [list(bases)])
    1327
    1328 - def _report_bad_base(self, base):
    1329 if not isinstance(base, ClassDoc): 1330 if not isinstance(base, GenericValueDoc): 1331 base_name = base.canonical_name 1332 elif base.parse_repr is not UNKNOWN: 1333 base_name = base.parse_repr 1334 else: 1335 base_name = '%r' % base 1336 log.warning("%s's base %s is not a class" % 1337 (self.canonical_name, base_name)) 1338 elif base.proxy_for is not None: 1339 log.warning("No information available for %s's base %s" % 1340 (self.canonical_name, base.proxy_for))
    1341
    1342 - def _c3_merge(self, seqs):
    1343 """ 1344 Helper function for L{_c3_mro}. 1345 """ 1346 res = [] 1347 while 1: 1348 nonemptyseqs=[seq for seq in seqs if seq] 1349 if not nonemptyseqs: return res 1350 for seq in nonemptyseqs: # find merge candidates among seq heads 1351 cand = seq[0] 1352 nothead=[s for s in nonemptyseqs if cand in s[1:]] 1353 if nothead: cand=None #reject candidate 1354 else: break 1355 if not cand: raise "Inconsistent hierarchy" 1356 res.append(cand) 1357 for seq in nonemptyseqs: # remove cand 1358 if seq[0] == cand: del seq[0]
    1359
    1360 - def select_variables(self, group=None, value_type=None, inherited=None, 1361 public=None, imported=None, detailed=None):
    1362 """ 1363 Return a specified subset of this class's L{sorted_variables} 1364 list. If C{value_type} is given, then only return variables 1365 whose values have the specified type. If C{group} is given, 1366 then only return variables that belong to the specified group. 1367 If C{inherited} is True, then only return inherited variables; 1368 if C{inherited} is False, then only return local variables. 1369 1370 @require: The L{sorted_variables} and L{variable_groups} 1371 attributes must be initialized before this method can be 1372 used. See L{init_sorted_variables()} and 1373 L{init_variable_groups()}. 1374 1375 @param value_type: A string specifying the value type for 1376 which variables should be returned. Valid values are: 1377 - 'instancemethod' - variables whose values are 1378 instance methods. 1379 - 'classmethod' - variables whose values are class 1380 methods. 1381 - 'staticmethod' - variables whose values are static 1382 methods. 1383 - 'properties' - variables whose values are properties. 1384 - 'class' - variables whose values are nested classes 1385 (including exceptions and types). 1386 - 'instancevariable' - instance variables. This includes 1387 any variables that are explicitly marked as instance 1388 variables with docstring fields; and variables with 1389 docstrings that are initialized in the constructor. 1390 - 'classvariable' - class variables. This includes any 1391 variables that are not included in any of the above 1392 categories. 1393 @type value_type: C{string} 1394 1395 @param group: The name of the group for which variables should 1396 be returned. A complete list of the groups defined by 1397 this C{ClassDoc} is available in the L{group_names} 1398 instance variable. The first element of this list is 1399 always the special group name C{''}, which is used for 1400 variables that do not belong to any group. 1401 @type group: C{string} 1402 1403 @param inherited: If C{None}, then return both inherited and 1404 local variables; if C{True}, then return only inherited 1405 variables; if C{False}, then return only local variables. 1406 1407 @param detailed: If True (False), return only the variables 1408 deserving (not deserving) a detailed informative box. 1409 If C{None}, don't care. 1410 @type detailed: C{bool} 1411 """ 1412 if (self.sorted_variables is UNKNOWN or 1413 self.variable_groups is UNKNOWN): 1414 raise ValueError('sorted_variables and variable_groups ' 1415 'must be initialized first.') 1416 1417 if group is None: var_list = self.sorted_variables 1418 else: var_list = self.variable_groups[group] 1419 1420 # Public/private filter (Count UNKNOWN as public) 1421 if public is True: 1422 var_list = [v for v in var_list if v.is_public is not False] 1423 elif public is False: 1424 var_list = [v for v in var_list if v.is_public is False] 1425 1426 # Inherited filter (Count UNKNOWN as non-inherited) 1427 if inherited is None: pass 1428 elif inherited: 1429 var_list = [v for v in var_list if v.container != self] 1430 else: 1431 var_list = [v for v in var_list if v.container == self ] 1432 1433 # Imported filter (Count UNKNOWN as non-imported) 1434 if imported is True: 1435 var_list = [v for v in var_list if v.is_imported is True] 1436 elif imported is False: 1437 var_list = [v for v in var_list if v.is_imported is not True] 1438 1439 # Detailed filter 1440 if detailed is True: 1441 var_list = [v for v in var_list if v.is_detailed() is True] 1442 elif detailed is False: 1443 var_list = [v for v in var_list if v.is_detailed() is not True] 1444 1445 if value_type is None: 1446 return var_list 1447 elif value_type == 'method': 1448 return [var_doc for var_doc in var_list 1449 if (isinstance(var_doc.value, RoutineDoc) and 1450 var_doc.is_instvar in (False, UNKNOWN))] 1451 elif value_type == 'instancemethod': 1452 return [var_doc for var_doc in var_list 1453 if (isinstance(var_doc.value, RoutineDoc) and 1454 not isinstance(var_doc.value, ClassMethodDoc) and 1455 not isinstance(var_doc.value, StaticMethodDoc) and 1456 var_doc.is_instvar in (False, UNKNOWN))] 1457 elif value_type == 'classmethod': 1458 return [var_doc for var_doc in var_list 1459 if (isinstance(var_doc.value, ClassMethodDoc) and 1460 var_doc.is_instvar in (False, UNKNOWN))] 1461 elif value_type == 'staticmethod': 1462 return [var_doc for var_doc in var_list 1463 if (isinstance(var_doc.value, StaticMethodDoc) and 1464 var_doc.is_instvar in (False, UNKNOWN))] 1465 elif value_type == 'property': 1466 return [var_doc for var_doc in var_list 1467 if (isinstance(var_doc.value, PropertyDoc) and 1468 var_doc.is_instvar in (False, UNKNOWN))] 1469 elif value_type == 'class': 1470 return [var_doc for var_doc in var_list 1471 if (isinstance(var_doc.value, ClassDoc) and 1472 var_doc.is_instvar in (False, UNKNOWN))] 1473 elif value_type == 'instancevariable': 1474 return [var_doc for var_doc in var_list 1475 if var_doc.is_instvar is True] 1476 elif value_type == 'classvariable': 1477 return [var_doc for var_doc in var_list 1478 if (var_doc.is_instvar in (False, UNKNOWN) and 1479 not isinstance(var_doc.value, 1480 (RoutineDoc, ClassDoc, PropertyDoc)))] 1481 else: 1482 raise ValueError('Bad value type %r' % value_type)
    1483
    1484 -class RoutineDoc(ValueDoc):
    1485 """ 1486 API documentation information about a single routine. 1487 """ 1488 #{ Signature 1489 posargs = UNKNOWN 1490 """@ivar: The names of the routine's positional arguments. 1491 If an argument list contains \"unpacking\" arguments, then 1492 their names will be specified using nested lists. E.g., if 1493 a function's argument list is C{((x1,y1), (x2,y2))}, then 1494 posargs will be C{[['x1','y1'], ['x2','y2']]}. 1495 @type: C{list}""" 1496 posarg_defaults = UNKNOWN 1497 """@ivar: API documentation for the positional arguments' 1498 default values. This list has the same length as C{posargs}, and 1499 each element of C{posarg_defaults} describes the corresponding 1500 argument in C{posargs}. For positional arguments with no default, 1501 C{posargs_defaults} will contain None. 1502 @type: C{list} of C{ValueDoc} or C{None}""" 1503 vararg = UNKNOWN 1504 """@ivar: The name of the routine's vararg argument, or C{None} if 1505 it has no vararg argument. 1506 @type: C{string} or C{None}""" 1507 kwarg = UNKNOWN 1508 """@ivar: The name of the routine's keyword argument, or C{None} if 1509 it has no keyword argument. 1510 @type: C{string} or C{None}""" 1511 lineno = UNKNOWN # used to look up profiling info from pstats. 1512 """@ivar: The line number of the first line of the function's 1513 signature. For Python functions, this is equal to 1514 C{func.func_code.co_firstlineno}. The first line of a file 1515 is considered line 1. 1516 @type: C{int}""" 1517 #} end of "signature" group 1518 1519 #{ Decorators 1520 decorators = UNKNOWN 1521 """@ivar: A list of names of decorators that were applied to this 1522 routine, in the order that they are listed in the source code. 1523 (I.e., in the reverse of the order that they were applied in.) 1524 @type: C{list} of C{string}""" 1525 #} end of "decorators" group 1526 1527 #{ Information Extracted from Docstrings 1528 arg_descrs = UNKNOWN 1529 """@ivar: A list of descriptions of the routine's 1530 arguments. Each element of this list is a tuple C{(args, 1531 descr)}, where C{args} is a list of argument names; and 1532 C{descr} is a L{ParsedDocstring 1533 <epydoc.markup.ParsedDocstring>} describing the argument(s) 1534 specified by C{arg}. 1535 @type: C{list}""" 1536 arg_types = UNKNOWN 1537 """@ivar: Descriptions of the expected types for the 1538 routine's arguments, encoded as a dictionary mapping from 1539 argument names to type descriptions. 1540 @type: C{dict} from C{string} to L{ParsedDocstring 1541 <epydoc.markup.ParsedDocstring>}""" 1542 return_descr = UNKNOWN 1543 """@ivar: A description of the value returned by this routine. 1544 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1545 return_type = UNKNOWN 1546 """@ivar: A description of expected type for the value 1547 returned by this routine. 1548 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1549 exception_descrs = UNKNOWN 1550 """@ivar: A list of descriptions of exceptions 1551 that the routine might raise. Each element of this list is a 1552 tuple C{(exc, descr)}, where C{exc} is a string contianing the 1553 exception name; and C{descr} is a L{ParsedDocstring 1554 <epydoc.markup.ParsedDocstring>} describing the circumstances 1555 under which the exception specified by C{exc} is raised. 1556 @type: C{list}""" 1557 #} end of "information extracted from docstrings" group 1558 callgraph_uid = None 1559 """@ivar: L{DotGraph}.uid of the call graph for the function. 1560 @type: C{str}""" 1561
    1562 - def is_detailed(self):
    1563 if super(RoutineDoc, self).is_detailed(): 1564 return True 1565 1566 if self.arg_descrs not in (None, UNKNOWN) and self.arg_descrs: 1567 return True 1568 1569 if self.arg_types not in (None, UNKNOWN) and self.arg_types: 1570 return True 1571 1572 if self.return_descr not in (None, UNKNOWN): 1573 return True 1574 1575 if self.exception_descrs not in (None, UNKNOWN) and self.exception_descrs: 1576 return True 1577 1578 if (self.decorators not in (None, UNKNOWN) 1579 and [ d for d in self.decorators 1580 if d not in ('classmethod', 'staticmethod') ]): 1581 return True 1582 1583 return False
    1584
    1585 - def all_args(self):
    1586 """ 1587 @return: A list of the names of all arguments (positional, 1588 vararg, and keyword), in order. If a positional argument 1589 consists of a tuple of names, then that tuple will be 1590 flattened. 1591 """ 1592 if self.posargs is UNKNOWN: 1593 return UNKNOWN 1594 1595 all_args = _flatten(self.posargs) 1596 if self.vararg not in (None, UNKNOWN): 1597 all_args.append(self.vararg) 1598 if self.kwarg not in (None, UNKNOWN): 1599 all_args.append(self.kwarg) 1600 return all_args
    1601
    1602 -def _flatten(lst, out=None):
    1603 """ 1604 Return a flattened version of C{lst}. 1605 """ 1606 if out is None: out = [] 1607 for elt in lst: 1608 if isinstance(elt, (list,tuple)): 1609 _flatten(elt, out) 1610 else: 1611 out.append(elt) 1612 return out
    1613
    1614 -class ClassMethodDoc(RoutineDoc): pass
    1615 -class StaticMethodDoc(RoutineDoc): pass
    1616
    1617 -class PropertyDoc(ValueDoc):
    1618 """ 1619 API documentation information about a single property. 1620 """ 1621 #{ Property Access Functions 1622 fget = UNKNOWN 1623 """@ivar: API documentation for the property's get function. 1624 @type: L{RoutineDoc}""" 1625 fset = UNKNOWN 1626 """@ivar: API documentation for the property's set function. 1627 @type: L{RoutineDoc}""" 1628 fdel = UNKNOWN 1629 """@ivar: API documentation for the property's delete function. 1630 @type: L{RoutineDoc}""" 1631 #} 1632 #{ Information Extracted from Docstrings 1633 type_descr = UNKNOWN 1634 """@ivar: A description of the property's expected type, extracted 1635 from its docstring. 1636 @type: L{ParsedDocstring<epydoc.markup.ParsedDocstring>}""" 1637 #} end of "information extracted from docstrings" group 1638 1645
    1646 - def is_detailed(self):
    1647 if super(PropertyDoc, self).is_detailed(): 1648 return True 1649 1650 if self.fget not in (None, UNKNOWN) and self.fget.pyval is not None: 1651 return True 1652 if self.fset not in (None, UNKNOWN) and self.fset.pyval is not None: 1653 return True 1654 if self.fdel not in (None, UNKNOWN) and self.fdel.pyval is not None: 1655 return True 1656 1657 return False
    1658 1659 ###################################################################### 1660 ## Index 1661 ###################################################################### 1662
    1663 -class DocIndex:
    1664 """ 1665 [xx] out of date. 1666 1667 An index that .. hmm... it *can't* be used to access some things, 1668 cuz they're not at the root level. Do I want to add them or what? 1669 And if so, then I have a sort of a new top level. hmm.. so 1670 basically the question is what to do with a name that's not in the 1671 root var's name space. 2 types: 1672 - entirely outside (eg os.path) 1673 - inside but not known (eg a submodule that we didn't look at?) 1674 - container of current thing not examined? 1675 1676 An index of all the C{APIDoc} objects that can be reached from a 1677 root set of C{ValueDoc}s. 1678 1679 The members of this index can be accessed by dotted name. In 1680 particular, C{DocIndex} defines two mappings, accessed via the 1681 L{get_vardoc()} and L{get_valdoc()} methods, which can be used to 1682 access C{VariableDoc}s or C{ValueDoc}s respectively by name. (Two 1683 separate mappings are necessary because a single name can be used 1684 to refer to both a variable and to the value contained by that 1685 variable.) 1686 1687 Additionally, the index defines two sets of C{ValueDoc}s: 1688 \"reachable C{ValueDoc}s\" and \"contained C{ValueDoc}s\". The 1689 X{reachable C{ValueDoc}s} are defined as the set of all 1690 C{ValueDoc}s that can be reached from the root set by following 1691 I{any} sequence of pointers to C{ValueDoc}s or C{VariableDoc}s. 1692 The X{contained C{ValueDoc}s} are defined as the set of all 1693 C{ValueDoc}s that can be reached from the root set by following 1694 only the C{ValueDoc} pointers defined by non-imported 1695 C{VariableDoc}s. For example, if the root set contains a module 1696 C{m}, then the contained C{ValueDoc}s includes the C{ValueDoc}s 1697 for any functions, variables, or classes defined in that module, 1698 as well as methods and variables defined in classes defined in the 1699 module. The reachable C{ValueDoc}s includes all of those 1700 C{ValueDoc}s, as well as C{ValueDoc}s for any values imported into 1701 the module, and base classes for classes defined in the module. 1702 """ 1703
    1704 - def __init__(self, root):
    1705 """ 1706 Create a new documentation index, based on the given root set 1707 of C{ValueDoc}s. If any C{APIDoc}s reachable from the root 1708 set does not have a canonical name, then it will be assigned 1709 one. etc. 1710 1711 @param root: A list of C{ValueDoc}s. 1712 """ 1713 for apidoc in root: 1714 if apidoc.canonical_name in (None, UNKNOWN): 1715 raise ValueError("All APIdocs passed to DocIndexer " 1716 "must already have canonical names.") 1717 1718 # Initialize the root items list. We sort them by length in 1719 # ascending order. (This ensures that variables will shadow 1720 # submodules when appropriate.) 1721 # When the elements name is the same, list in alphabetical order: 1722 # this is needed by the check for duplicates below. 1723 self.root = sorted(root, 1724 key=lambda d: (len(d.canonical_name), d.canonical_name)) 1725 """The list of C{ValueDoc}s to document. 1726 @type: C{list}""" 1727 1728 # Drop duplicated modules 1729 # [xx] maybe what causes duplicates should be fixed instead. 1730 # If fixed, adjust the sort here above: sorting by names will not 1731 # be required anymore 1732 i = 1 1733 while i < len(self.root): 1734 if self.root[i-1] is self.root[i]: 1735 del self.root[i] 1736 else: 1737 i += 1 1738 1739 self.mlclasses = self._get_module_classes(self.root) 1740 """A mapping from class names to L{ClassDoc}. Contains 1741 classes defined at module level for modules in L{root} 1742 and which can be used as fallback by L{find()} if looking 1743 in containing namespaces fails. 1744 @type: C{dict} from C{str} to L{ClassDoc} or C{list}""" 1745 1746 self.callers = None 1747 """A dictionary mapping from C{RoutineDoc}s in this index 1748 to lists of C{RoutineDoc}s for the routine's callers. 1749 This dictionary is initialized by calling 1750 L{read_profiling_info()}. 1751 @type: C{list} of L{RoutineDoc}""" 1752 1753 self.callees = None 1754 """A dictionary mapping from C{RoutineDoc}s in this index 1755 to lists of C{RoutineDoc}s for the routine's callees. 1756 This dictionary is initialized by calling 1757 L{read_profiling_info()}. 1758 @type: C{list} of L{RoutineDoc}""" 1759 1760 self._funcid_to_doc = {} 1761 """A mapping from C{profile} function ids to corresponding 1762 C{APIDoc} objects. A function id is a tuple of the form 1763 C{(filename, lineno, funcname)}. This is used to update 1764 the L{callers} and L{callees} variables.""" 1765 1766 self._container_cache = {} 1767 """A cache for the L{container()} method, to increase speed.""" 1768 1769 self._get_cache = {} 1770 """A cache for the L{get_vardoc()} and L{get_valdoc()} methods, 1771 to increase speed."""
    1772 1773 #//////////////////////////////////////////////////////////// 1774 # Lookup methods 1775 #//////////////////////////////////////////////////////////// 1776 # [xx] 1777 # Currently these only work for things reachable from the 1778 # root... :-/ I might want to change this so that imported 1779 # values can be accessed even if they're not contained. 1780 # Also, I might want canonical names to not start with ?? 1781 # if the thing is a top-level imported module..? 1782
    1783 - def get_vardoc(self, name):
    1784 """ 1785 Return the C{VariableDoc} with the given name, or C{None} if this 1786 index does not contain a C{VariableDoc} with the given name. 1787 """ 1788 var, val = self._get(name) 1789 return var
    1790
    1791 - def get_valdoc(self, name):
    1792 """ 1793 Return the C{ValueDoc} with the given name, or C{None} if this 1794 index does not contain a C{ValueDoc} with the given name. 1795 """ 1796 var, val = self._get(name) 1797 return val
    1798
    1799 - def _get(self, name):
    1800 """ 1801 A helper function that's used to implement L{get_vardoc()} 1802 and L{get_valdoc()}. 1803 """ 1804 # Convert name to a DottedName, if necessary. 1805 if not isinstance(name, DottedName): 1806 name = DottedName(name) 1807 1808 # Check if the result is cached. 1809 val = self._get_cache.get(name) 1810 if val is not None: return val 1811 1812 # Look for an element in the root set whose name is a prefix 1813 # of `name`. If we can't find one, then return None. 1814 for root_valdoc in self.root: 1815 if root_valdoc.canonical_name.dominates(name): 1816 # Starting at the root valdoc, walk down the variable/ 1817 # submodule chain until we find the requested item. 1818 var_doc = None 1819 val_doc = root_valdoc 1820 for identifier in name[len(root_valdoc.canonical_name):]: 1821 if val_doc is None: break 1822 var_doc, val_doc = self._get_from(val_doc, identifier) 1823 else: 1824 # If we found it, then return. 1825 if var_doc is not None or val_doc is not None: 1826 self._get_cache[name] = (var_doc, val_doc) 1827 return var_doc, val_doc 1828 1829 # We didn't find it. 1830 self._get_cache[name] = (None, None) 1831 return None, None
    1832
    1833 - def _get_from(self, val_doc, identifier):
    1834 if isinstance(val_doc, NamespaceDoc): 1835 child_var = val_doc.variables.get(identifier) 1836 if child_var is not None: 1837 child_val = child_var.value 1838 if child_val is UNKNOWN: child_val = None 1839 return child_var, child_val 1840 1841 # If that fails, then see if it's a submodule. 1842 if (isinstance(val_doc, ModuleDoc) and 1843 val_doc.submodules is not UNKNOWN): 1844 for submodule in val_doc.submodules: 1845 if submodule.canonical_name[-1] == identifier: 1846 var_doc = None 1847 val_doc = submodule 1848 if val_doc is UNKNOWN: val_doc = None 1849 return var_doc, val_doc 1850 1851 return None, None
    1852
    1853 - def find(self, name, context):
    1854 """ 1855 Look for an C{APIDoc} named C{name}, relative to C{context}. 1856 Return the C{APIDoc} if one is found; otherwise, return 1857 C{None}. C{find} looks in the following places, in order: 1858 - Function parameters (if one matches, return C{None}) 1859 - All enclosing namespaces, from closest to furthest. 1860 - If C{name} starts with C{'self'}, then strip it off and 1861 look for the remaining part of the name using C{find} 1862 - Builtins 1863 - Parameter attributes 1864 - Classes at module level (if the name is not ambiguous) 1865 1866 @type name: C{str} or L{DottedName} 1867 @type context: L{APIDoc} 1868 """ 1869 if isinstance(name, basestring): 1870 name = re.sub(r'\(.*\)$', '', name.strip()) 1871 if re.match('^([a-zA-Z_]\w*)(\.[a-zA-Z_]\w*)*$', name): 1872 name = DottedName(name) 1873 else: 1874 return None 1875 elif not isinstance(name, DottedName): 1876 raise TypeError("'name' should be a string or DottedName") 1877 1878 if context is None or context.canonical_name is None: 1879 container_name = [] 1880 else: 1881 container_name = context.canonical_name 1882 1883 # Check for the name in all containing namespaces, starting 1884 # with the closest one. 1885 for i in range(len(container_name), -1, -1): 1886 relative_name = container_name[:i]+name 1887 # Is `name` the absolute name of a documented value? 1888 # (excepting GenericValueDoc values.) 1889 val_doc = self.get_valdoc(relative_name) 1890 if (val_doc is not None and 1891 not isinstance(val_doc, GenericValueDoc)): 1892 return val_doc 1893 # Is `name` the absolute name of a documented variable? 1894 var_doc = self.get_vardoc(relative_name) 1895 if var_doc is not None: return var_doc 1896 1897 # If the name begins with 'self', then try stripping that off 1898 # and see if we can find the variable. 1899 if name[0] == 'self': 1900 doc = self.find('.'.join(name[1:]), context) 1901 if doc is not None: return doc 1902 1903 # Is it the name of a builtin? 1904 if len(name)==1 and hasattr(__builtin__, name[0]): 1905 return None 1906 1907 # Is it a parameter's name or an attribute of a parameter? 1908 if isinstance(context, RoutineDoc): 1909 all_args = context.all_args() 1910 if all_args is not UNKNOWN and name[0] in all_args: 1911 return None 1912 1913 # Is this an object directly contained by any module? 1914 doc = self.mlclasses.get(name[-1]) 1915 if isinstance(doc, APIDoc): 1916 return doc 1917 elif isinstance(doc, list): 1918 log.warning("%s is an ambiguous name: it may be %s" % ( 1919 name[-1], 1920 ", ".join([ "'%s'" % d.canonical_name for d in doc ]))) 1921 1922 # Drop this item so that the warning is reported only once. 1923 # fail() will fail anyway. 1924 del self.mlclasses[name[-1]]
    1925
    1926 - def _get_module_classes(self, docs):
    1927 """ 1928 Gather all the classes defined in a list of modules. 1929 1930 Very often people refers to classes only by class name, 1931 even if they are not imported in the namespace. Linking 1932 to such classes will fail if we look for them only in nested 1933 namespaces. Allow them to retrieve only by name. 1934 1935 @param docs: containers of the objects to collect 1936 @type docs: C{list} of C{APIDoc} 1937 @return: mapping from objects name to the object(s) with that name 1938 @rtype: C{dict} from C{str} to L{ClassDoc} or C{list} 1939 """ 1940 classes = {} 1941 for doc in docs: 1942 if not isinstance(doc, ModuleDoc): 1943 continue 1944 1945 for var in doc.variables.values(): 1946 if not isinstance(var.value, ClassDoc): 1947 continue 1948 1949 val = var.value 1950 if val in (None, UNKNOWN) or val.defining_module is not doc: 1951 continue 1952 if val.canonical_name in (None, UNKNOWN): 1953 continue 1954 1955 name = val.canonical_name[-1] 1956 vals = classes.get(name) 1957 if vals is None: 1958 classes[name] = val 1959 elif not isinstance(vals, list): 1960 classes[name] = [ vals, val ] 1961 else: 1962 vals.append(val) 1963 1964 return classes
    1965 1966 #//////////////////////////////////////////////////////////// 1967 # etc 1968 #//////////////////////////////////////////////////////////// 1969
    1970 - def reachable_valdocs(self, **filters):
    1971 """ 1972 Return a list of all C{ValueDoc}s that can be reached, 1973 directly or indirectly from this C{DocIndex}'s root set. 1974 1975 @param filters: A set of filters that can be used to prevent 1976 C{reachable_valdocs} from following specific link types 1977 when looking for C{ValueDoc}s that can be reached from the 1978 root set. See C{APIDoc.apidoc_links} for a more complete 1979 description. 1980 """ 1981 return reachable_valdocs(self.root, **filters)
    1982
    1983 - def container(self, api_doc):
    1984 """ 1985 Return the C{ValueDoc} that contains the given C{APIDoc}, or 1986 C{None} if its container is not in the index. 1987 """ 1988 # Check if the result is cached. 1989 val = self._container_cache.get(api_doc) 1990 if val is not None: return val 1991 1992 if isinstance(api_doc, GenericValueDoc): 1993 self._container_cache[api_doc] = None 1994 return None # [xx] unknown. 1995 if isinstance(api_doc, VariableDoc): 1996 self._container_cache[api_doc] = api_doc.container 1997 return api_doc.container 1998 if len(api_doc.canonical_name) == 1: 1999 self._container_cache[api_doc] = None 2000 return None 2001 elif isinstance(api_doc, ModuleDoc) and api_doc.package is not UNKNOWN: 2002 self._container_cache[api_doc] = api_doc.package 2003 return api_doc.package 2004 else: 2005 parent = self.get_valdoc(api_doc.canonical_name.container()) 2006 self._container_cache[api_doc] = parent 2007 return parent
    2008 2009 #//////////////////////////////////////////////////////////// 2010 # Profiling information 2011 #//////////////////////////////////////////////////////////// 2012
    2013 - def read_profiling_info(self, profile_stats):
    2014 """ 2015 Initialize the L{callers} and L{callees} variables, given a 2016 C{Stat} object from the C{pstats} module. 2017 2018 @warning: This method uses undocumented data structures inside 2019 of C{profile_stats}. 2020 """ 2021 if self.callers is None: self.callers = {} 2022 if self.callees is None: self.callees = {} 2023 2024 # The Stat object encodes functions using `funcid`s, or 2025 # tuples of (filename, lineno, funcname). Create a mapping 2026 # from these `funcid`s to `RoutineDoc`s. 2027 self._update_funcid_to_doc(profile_stats) 2028 2029 for callee, (cc, nc, tt, ct, callers) in profile_stats.stats.items(): 2030 callee = self._funcid_to_doc.get(callee) 2031 if callee is None: continue 2032 for caller in callers: 2033 caller = self._funcid_to_doc.get(caller) 2034 if caller is None: continue 2035 self.callers.setdefault(callee, []).append(caller) 2036 self.callees.setdefault(caller, []).append(callee)
    2037
    2038 - def _update_funcid_to_doc(self, profile_stats):
    2039 """ 2040 Update the dictionary mapping from C{pstat.Stat} funciton ids to 2041 C{RoutineDoc}s. C{pstat.Stat} function ids are tuples of 2042 C{(filename, lineno, funcname)}. 2043 """ 2044 # Maps (filename, lineno, funcname) -> RoutineDoc 2045 for val_doc in self.reachable_valdocs(): 2046 # We only care about routines. 2047 if not isinstance(val_doc, RoutineDoc): continue 2048 # Get the filename from the defining module. 2049 module = val_doc.defining_module 2050 if module is UNKNOWN or module.filename is UNKNOWN: continue 2051 # Normalize the filename. 2052 filename = os.path.abspath(module.filename) 2053 try: filename = py_src_filename(filename) 2054 except: pass 2055 # Look up the stat_func_id 2056 funcid = (filename, val_doc.lineno, val_doc.canonical_name[-1]) 2057 if funcid in profile_stats.stats: 2058 self._funcid_to_doc[funcid] = val_doc
    2059 2060 ###################################################################### 2061 ## Pretty Printing 2062 ###################################################################### 2063
    2064 -def pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(), 2065 backpointers=None):
    2066 """ 2067 @return: A multiline pretty-printed string representation for the 2068 given C{APIDoc}. 2069 @param doublespace: If true, then extra lines will be 2070 inserted to make the output more readable. 2071 @param depth: The maximum depth that pp_apidoc will descend 2072 into descendent VarDocs. To put no limit on 2073 depth, use C{depth=-1}. 2074 @param exclude: A list of names of attributes whose values should 2075 not be shown. 2076 @param backpointers: For internal use. 2077 """ 2078 pyid = id(api_doc.__dict__) 2079 if backpointers is None: backpointers = {} 2080 if (hasattr(api_doc, 'canonical_name') and 2081 api_doc.canonical_name not in (None, UNKNOWN)): 2082 name = '%s for %s' % (api_doc.__class__.__name__, 2083 api_doc.canonical_name) 2084 elif getattr(api_doc, 'name', None) not in (UNKNOWN, None): 2085 if (getattr(api_doc, 'container', None) not in (UNKNOWN, None) and 2086 getattr(api_doc.container, 'canonical_name', None) 2087 not in (UNKNOWN, None)): 2088 name ='%s for %s' % (api_doc.__class__.__name__, 2089 api_doc.container.canonical_name+ 2090 api_doc.name) 2091 else: 2092 name = '%s for %s' % (api_doc.__class__.__name__, api_doc.name) 2093 else: 2094 name = api_doc.__class__.__name__ 2095 2096 if pyid in backpointers: 2097 return '%s [%s] (defined above)' % (name, backpointers[pyid]) 2098 2099 if depth == 0: 2100 if hasattr(api_doc, 'name') and api_doc.name is not None: 2101 return '%s...' % api_doc.name 2102 else: 2103 return '...' 2104 2105 backpointers[pyid] = len(backpointers) 2106 s = '%s [%s]' % (name, backpointers[pyid]) 2107 2108 # Only print non-empty fields: 2109 fields = [field for field in api_doc.__dict__.keys() 2110 if (field in include or 2111 (getattr(api_doc, field) is not UNKNOWN 2112 and field not in exclude))] 2113 if include: 2114 fields = [field for field in dir(api_doc) 2115 if field in include] 2116 else: 2117 fields = [field for field in api_doc.__dict__.keys() 2118 if (getattr(api_doc, field) is not UNKNOWN 2119 and field not in exclude)] 2120 fields.sort() 2121 2122 for field in fields: 2123 fieldval = getattr(api_doc, field) 2124 if doublespace: s += '\n |' 2125 s += '\n +- %s' % field 2126 2127 if (isinstance(fieldval, types.ListType) and 2128 len(fieldval)>0 and 2129 isinstance(fieldval[0], APIDoc)): 2130 s += _pp_list(api_doc, fieldval, doublespace, depth, 2131 exclude, include, backpointers, 2132 (field is fields[-1])) 2133 elif (isinstance(fieldval, types.DictType) and 2134 len(fieldval)>0 and 2135 isinstance(fieldval.values()[0], APIDoc)): 2136 s += _pp_dict(api_doc, fieldval, doublespace, 2137 depth, exclude, include, backpointers, 2138 (field is fields[-1])) 2139 elif isinstance(fieldval, APIDoc): 2140 s += _pp_apidoc(api_doc, fieldval, doublespace, depth, 2141 exclude, include, backpointers, 2142 (field is fields[-1])) 2143 else: 2144 s += ' = ' + _pp_val(api_doc, fieldval, doublespace, 2145 depth, exclude, include, backpointers) 2146 2147 return s
    2148
    2149 -def _pp_list(api_doc, items, doublespace, depth, exclude, include, 2150 backpointers, is_last):
    2151 line1 = (is_last and ' ') or '|' 2152 s = '' 2153 for item in items: 2154 line2 = ((item is items[-1]) and ' ') or '|' 2155 joiner = '\n %s %s ' % (line1, line2) 2156 if doublespace: s += '\n %s |' % line1 2157 s += '\n %s +- ' % line1 2158 valstr = _pp_val(api_doc, item, doublespace, depth, exclude, include, 2159 backpointers) 2160 s += joiner.join(valstr.split('\n')) 2161 return s
    2162
    2163 -def _pp_dict(api_doc, dict, doublespace, depth, exclude, include, 2164 backpointers, is_last):
    2165 items = dict.items() 2166 items.sort() 2167 line1 = (is_last and ' ') or '|' 2168 s = '' 2169 for item in items: 2170 line2 = ((item is items[-1]) and ' ') or '|' 2171 joiner = '\n %s %s ' % (line1, line2) 2172 if doublespace: s += '\n %s |' % line1 2173 s += '\n %s +- ' % line1 2174 valstr = _pp_val(api_doc, item[1], doublespace, depth, exclude, 2175 include, backpointers) 2176 s += joiner.join(('%s => %s' % (item[0], valstr)).split('\n')) 2177 return s
    2178
    2179 -def _pp_apidoc(api_doc, val, doublespace, depth, exclude, include, 2180 backpointers, is_last):
    2181 line1 = (is_last and ' ') or '|' 2182 s = '' 2183 if doublespace: s += '\n %s | ' % line1 2184 s += '\n %s +- ' % line1 2185 joiner = '\n %s ' % line1 2186 childstr = pp_apidoc(val, doublespace, depth-1, exclude, 2187 include, backpointers) 2188 return s + joiner.join(childstr.split('\n'))
    2189
    2190 -def _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers):
    2191 from epydoc import markup 2192 if isinstance(val, APIDoc): 2193 return pp_apidoc(val, doublespace, depth-1, exclude, 2194 include, backpointers) 2195 elif isinstance(val, markup.ParsedDocstring): 2196 valrepr = `val.to_plaintext(None)` 2197 if len(valrepr) < 40: return valrepr 2198 else: return valrepr[:37]+'...' 2199 else: 2200 valrepr = repr(val) 2201 if len(valrepr) < 40: return valrepr 2202 else: return valrepr[:37]+'...'
    2203

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docparser-module.html0000644000175000017500000002307010750103050023704 0ustar pronovicpronovic docparser

    Module docparser


    Classes

    ParseError

    Functions

    add_docstring_from_comments
    add_to_group
    apply_decorator
    del_variable
    dotted_names_in
    find_base
    flatten
    get_lhs_parent
    get_module_encoding
    handle_special_module_vars
    init_arglist
    lhs_is_instvar
    lookup_name
    lookup_value
    lookup_variable
    parse_classdef_bases
    parse_docs
    parse_dotted_name
    parse_dotted_name_list
    parse_funcdef_arg
    parse_name
    parse_string
    parse_string_list
    pp_toktree
    process_assignment
    process_classdef
    process_control_flow_line
    process_del
    process_docstring
    process_file
    process_from_import
    process_funcdef
    process_import
    process_line
    process_multi_stmt
    process_one_line_block
    rhs_to_valuedoc
    script_guard
    set_variable
    shallow_parse
    split_on

    Variables

    BASE_HANDLING
    COMMENT_DOCSTRING_MARKER
    CONTROL_FLOW_KEYWORDS
    DEFAULT_DECORATOR_BEHAVIOR
    END_GROUP_MARKER
    IMPORT_HANDLING
    IMPORT_STAR_HANDLING
    PARSE_ELSE_BLOCKS
    PARSE_EXCEPT_BLOCKS
    PARSE_FINALLY_BLOCKS
    PARSE_FOR_BLOCKS
    PARSE_IF_BLOCKS
    PARSE_TRY_BLOCKS
    PARSE_WHILE_BLOCKS
    START_GROUP_MARKER

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup.Field-class.html0000644000175000017500000004473610750103050023314 0ustar pronovicpronovic epydoc.markup.Field
    Package epydoc :: Package markup :: Class Field
    [hide private]
    [frames] | no frames]

    Class Field

    source code

    The contents of a docstring's field. Docstring fields are used to describe specific aspects of an object, such as a parameter of a function or the author of a module. Each field consists of a tag, an optional argument, and a body:

    • The tag specifies the type of information that the field encodes.
    • The argument specifies the object that the field describes. The argument may be None or a string.
    • The body contains the field's information.

    Tags are automatically downcased and stripped; and arguments are automatically stripped.

    Instance Methods [hide private]
     
    __init__(self, tag, arg, body) source code
    call graph 
    string
    tag(self)
    Returns: This field's tag.
    source code
    call graph 
    string or None
    arg(self)
    Returns: This field's argument, or None if this field has no argument.
    source code
    call graph 
    ParsedDocstring
    body(self)
    Returns: This field's body.
    source code
    call graph 
     
    __repr__(self) source code
    Method Details [hide private]

    tag(self)

    source code 
    call graph 
    Returns: string
    This field's tag.

    arg(self)

    source code 
    call graph 
    Returns: string or None
    This field's argument, or None if this field has no argument.

    body(self)

    source code 
    call graph 
    Returns: ParsedDocstring
    This field's body.

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.html_help-module.html0000644000175000017500000000212710750103050025677 0ustar pronovicpronovic html_help

    Module html_help


    Variables

    HTML_HELP

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.GenericValueDoc-class.html0000644000175000017500000006406710750103050025227 0ustar pronovicpronovic epydoc.apidoc.GenericValueDoc
    Package epydoc :: Module apidoc :: Class GenericValueDoc
    [hide private]
    [frames] | no frames]

    Class GenericValueDoc

    source code


    API documentation about a 'generic' value, i.e., one that does not have its own docstring or any information other than its value and parse representation. GenericValueDocs do not get assigned cannonical names.

    Instance Methods [hide private]
    bool
    is_detailed(self)
    Does this object deserve a box with extra details?
    source code

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__, apidoc_links

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
    DottedName canonical_name = None
    A dotted name that serves as a unique identifier for this ValueDoc's value.
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from ValueDoc: toktree

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Information Extracted from Docstrings

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    is_detailed(self)

    source code 

    Does this object deserve a box with extra details?

    Returns: bool
    True if the object needs extra details, else False.
    Overrides: APIDoc.is_detailed
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.test-module.html0000644000175000017500000002124410750103050022117 0ustar pronovicpronovic epydoc.test
    Package epydoc :: Package test
    [hide private]
    [frames] | no frames]

    Package test

    source code

    Regression testing.

    Submodules [hide private]

    Functions [hide private]
     
    main() source code
     
    check_requirements(filename)
    Search for strings of the form:
    source code
    Function Details [hide private]

    check_requirements(filename)

    source code 

    Search for strings of the form:

       [Require: <module>]
    

    If any are found, then try importing the module named <module>. If the import fails, then return False. If all required modules are found, return True. (This includes the case where no requirements are listed.)


    epydoc-3.0.1+dfsg/doc/api/frames.html0000644000175000017500000000110110750103050017636 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/api/epydoc.markup.DocstringLinker-class.html0000644000175000017500000003107310750103050025360 0ustar pronovicpronovic epydoc.markup.DocstringLinker
    Package epydoc :: Package markup :: Class DocstringLinker
    [hide private]
    [frames] | no frames]

    Class DocstringLinker

    source code


    A translator for crossreference links into and out of a ParsedDocstring. DocstringLinker is used by ParsedDocstring to convert these crossreference links into appropriate output formats. For example, DocstringLinker.to_html expects a DocstringLinker that converts crossreference links to HTML.

    Instance Methods [hide private]
    string
    translate_identifier_xref(self, identifier, label=None)
    Translate a crossreference link to a Python identifier to the appropriate output format.
    source code
    string
    translate_indexterm(self, indexterm)
    Translate an index term to the appropriate output format.
    source code
    Method Details [hide private]

    translate_identifier_xref(self, identifier, label=None)

    source code 

    Translate a crossreference link to a Python identifier to the appropriate output format. The output will typically include a reference or pointer to the crossreference target.

    Parameters:
    • identifier (string) - The name of the Python identifier that should be linked to.
    • label (string or None) - The label that should be used for the identifier, if it's different from the name of the identifier.
    Returns: string
    The translated crossreference link.

    translate_indexterm(self, indexterm)

    source code 

    Translate an index term to the appropriate output format. The output will typically include a crossreference anchor.

    Parameters:
    Returns: string
    The translated index term.

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.latex-module.html0000644000175000017500000000211410750103050025034 0ustar pronovicpronovic latex

    Module latex


    Classes

    LatexWriter

    [hide private] epydoc-3.0.1+dfsg/doc/api/redirect.html0000644000175000017500000001147410750103050020200 0ustar pronovicpronovicEpydoc Redirect Page

    Epydoc Auto-redirect page

    When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

     

    epydoc-3.0.1+dfsg/doc/api/index.html0000644000175000017500000000110110750103050017470 0ustar pronovicpronovic epydoc epydoc-3.0.1+dfsg/doc/api/epydoc.docbuilder.BuildOptions-class.html0000644000175000017500000004755610750103050025524 0ustar pronovicpronovic epydoc.docbuilder.BuildOptions
    Package epydoc :: Module docbuilder :: Class BuildOptions
    [hide private]
    [frames] | no frames]

    Class BuildOptions

    source code

    Holds the parameters for a documentation building process.

    Instance Methods [hide private]
     
    __init__(self, introspect=True, parse=True, exclude_introspect=None, exclude_parse=None, add_submodules=True) source code
    call graph 
     
    must_introspect(self, name)
    Return True if a module is to be introsepcted with the current settings.
    source code
    call graph 
     
    must_parse(self, name)
    Return True if a module is to be parsed with the current settings.
    source code
    call graph 
    bool
    _matches_filter(self, name, regexp)
    Test if a module name matches a pattern.
    source code
    call graph 
    Method Details [hide private]

    must_introspect(self, name)

    source code 
    call graph 

    Return True if a module is to be introsepcted with the current settings.

    Parameters:
    • name (DottedName or str) - The name of the module to test

    must_parse(self, name)

    source code 
    call graph 

    Return True if a module is to be parsed with the current settings.

    Parameters:
    • name (DottedName or str) - The name of the module to test

    _matches_filter(self, name, regexp)

    source code 
    call graph 

    Test if a module name matches a pattern.

    Parameters:
    • name (DottedName or str) - The name of the module to test
    • regexp (pattern) - The pattern object to match name against. If None, return False
    Returns: bool
    True if name in dotted format matches regexp, else False

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup-module.html0000644000175000017500000000473010750103050023223 0ustar pronovicpronovic markup

    Module markup


    Classes

    ConcatenatedDocstring
    DocstringLinker
    Field
    ParseError
    ParsedDocstring

    Functions

    parse
    parse_type_of
    register_markup_language

    Variables

    MARKUP_LANGUAGES_USED
    SCRWIDTH

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_help-module.html0000644000175000017500000001770410750103050025123 0ustar pronovicpronovic epydoc.docwriter.html_help
    Package epydoc :: Package docwriter :: Module html_help
    [hide private]
    [frames] | no frames]

    Module html_help

    source code

    Default help file for the HTML outputter (epydoc.docwriter.html).

    Variables [hide private]
    string HTML_HELP = '\n<h1 class="epydoc"> API Documentation </h1>\n\n...
    The contents of the HTML body for the default help page.
    Variables Details [hide private]

    HTML_HELP

    The contents of the HTML body for the default help page.
    Type:
    string
    Value:
    '''
    <h1 class="epydoc"> API Documentation </h1>
    
    <p> This document contains the API (Application Programming Interface)
    documentation for %(this_project)s.  Documentation for the Python
    objects defined by the project is divided into separate pages for each
    package, module, and class.  The API documentation also includes two
    pages containing information about the project as a whole: a trees
    ...
    

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docbuilder-module.html0000644000175000017500000001452610750103050024044 0ustar pronovicpronovic docbuilder

    Module docbuilder


    Classes

    BuildOptions

    Functions

    assign_canonical_names
    build_doc
    build_doc_index
    find_overrides
    inherit_docs
    link_imports
    merge_attribute
    merge_bases
    merge_docs
    merge_docs_extracted_by
    merge_docstring
    merge_fdel
    merge_fget
    merge_fset
    merge_overrides
    merge_posarg_defaults
    merge_proxy_for
    merge_submodules
    merge_value
    merge_variables
    register_attribute_mergefunc

    Variables

    DEFAULT_MERGE_PRECEDENCE
    MERGE_PRECEDENCE

    [hide private] epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.html_css-module.html0000644000175000017500000000532010750103050025535 0ustar pronovicpronovic html_css

    Module html_css


    Functions

    _rv

    Variables

    STYLESHEETS
    TEMPLATE

    [hide private] epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.plaintext-module.html0000644000175000017500000000240410750103050025226 0ustar pronovicpronovic plaintext

    Module plaintext


    Classes

    ParsedPlaintextDocstring

    Functions

    parse_docstring

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink.VoidUrlGenerator-class.html0000644000175000017500000003055010750103050027340 0ustar pronovicpronovic epydoc.docwriter.xlink.VoidUrlGenerator
    Package epydoc :: Package docwriter :: Module xlink :: Class VoidUrlGenerator
    [hide private]
    [frames] | no frames]

    Class VoidUrlGenerator

    source code


    Don't actually know any url, but don't report any error.

    Useful if an index file is not available, but a document linking to it is to be generated, and warnings are to be avoided.

    Don't report any object as missing, Don't return any url anyway.

    Nested Classes [hide private]

    Inherited from UrlGenerator: IndexAmbiguous

    Instance Methods [hide private]
    str
    get_url(self, name)
    Look for a name and return the matching URL documentation.
    source code

    Inherited from UrlGenerator: get_canonical_name

    Class Variables [hide private]

    Inherited from UrlGenerator (private): _SEP_RE

    Method Details [hide private]

    get_url(self, name)

    source code 

    Look for a name and return the matching URL documentation.

    First look for a fully qualified name. If not found, try with partial name.

    If no url exists for the given object, return None.

    Parameters:
    • name - the name to look for
    Returns: str
    the URL that can be used to reach the name documentation. None if no such URL exists.
    Raises:
    • IndexError - no object found with name
    • DocUrlGenerator.IndexAmbiguous - more than one object found with a non-fully qualified name; notice that this is an IndexError subclass
    Overrides: UrlGenerator.get_url
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.cli-pysrc.html0000644000175000017500000175531610750103050021601 0ustar pronovicpronovic epydoc.cli
    Package epydoc :: Module cli
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.cli

       1  # epydoc -- Command line interface 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: cli.py 1678 2008-01-29 17:21:29Z edloper $ 
       8   
       9  """ 
      10  Command-line interface for epydoc.  Abbreviated Usage:: 
      11   
      12   epydoc [options] NAMES... 
      13    
      14       NAMES...                  The Python modules to document. 
      15       --html                    Generate HTML output (default). 
      16       --latex                   Generate LaTeX output. 
      17       --pdf                     Generate pdf output, via LaTeX. 
      18       -o DIR, --output DIR      The output directory. 
      19       --inheritance STYLE       The format for showing inherited objects. 
      20       -V, --version             Print the version of epydoc. 
      21       -h, --help                Display a usage message. 
      22   
      23  Run \"epydoc --help\" for a complete option list.  See the epydoc(1) 
      24  man page for more information. 
      25   
      26  Config Files 
      27  ============ 
      28  Configuration files can be specified with the C{--config} option. 
      29  These files are read using U{ConfigParser 
      30  <http://docs.python.org/lib/module-ConfigParser.html>}.  Configuration 
      31  files may set options or add names of modules to document.  Option 
      32  names are (usually) identical to the long names of command line 
      33  options.  To specify names to document, use any of the following 
      34  option names:: 
      35   
      36    module modules value values object objects 
      37   
      38  A simple example of a config file is:: 
      39   
      40    [epydoc] 
      41    modules: sys, os, os.path, re, %(MYSANDBOXPATH)/utilities.py 
      42    name: Example 
      43    graph: classtree 
      44    introspect: no 
      45   
      46  All ConfigParser interpolations are done using local values and the 
      47  environment variables. 
      48   
      49   
      50  Verbosity Levels 
      51  ================ 
      52  The C{-v} and C{-q} options increase and decrease verbosity, 
      53  respectively.  The default verbosity level is zero.  The verbosity 
      54  levels are currently defined as follows:: 
      55   
      56                  Progress    Markup warnings   Warnings   Errors 
      57   -3               none            no             no        no 
      58   -2               none            no             no        yes 
      59   -1               none            no             yes       yes 
      60    0 (default)     bar             no             yes       yes 
      61    1               bar             yes            yes       yes 
      62    2               list            yes            yes       yes 
      63  """ 
      64  __docformat__ = 'epytext en' 
      65   
      66  import sys, os, time, re, pickle, textwrap 
      67  from glob import glob 
      68  from optparse import OptionParser, OptionGroup, SUPPRESS_HELP 
      69  import optparse 
      70  import epydoc 
      71  from epydoc import log 
      72  from epydoc.util import wordwrap, run_subprocess, RunSubprocessError 
      73  from epydoc.util import plaintext_to_html 
      74  from epydoc.apidoc import UNKNOWN 
      75  from epydoc.compat import * 
      76  import ConfigParser 
      77  from epydoc.docwriter.html_css import STYLESHEETS as CSS_STYLESHEETS 
      78   
      79  # This module is only available if Docutils are in the system 
      80  try: 
      81      from epydoc.docwriter import xlink 
      82  except: 
      83      xlink = None 
      84   
      85  INHERITANCE_STYLES = ('grouped', 'listed', 'included') 
      86  GRAPH_TYPES = ('classtree', 'callgraph', 'umlclasstree') 
      87  ACTIONS = ('html', 'text', 'latex', 'dvi', 'ps', 'pdf', 'check') 
      88  DEFAULT_DOCFORMAT = 'epytext' 
      89  PROFILER = 'profile' #: Which profiler to use: 'hotshot' or 'profile' 
      90   
      91  ###################################################################### 
      92  #{ Help Topics 
      93  ###################################################################### 
      94   
      95  DOCFORMATS = ('epytext', 'plaintext', 'restructuredtext', 'javadoc') 
      96  HELP_TOPICS = { 
      97      'docformat': textwrap.dedent('''\ 
      98          __docformat__ is a module variable that specifies the markup 
      99          language for the docstrings in a module.  Its value is a  
     100          string, consisting the name of a markup language, optionally  
     101          followed by a language code (such as "en" for English).  Epydoc 
     102          currently recognizes the following markup language names: 
     103          ''' + ', '.join(DOCFORMATS)), 
     104      'inheritance': textwrap.dedent('''\ 
     105          The following inheritance formats are currently supported: 
     106              - grouped: inherited objects are gathered into groups, 
     107                based on what class they were inherited from. 
     108              - listed: inherited objects are listed in a short list 
     109                at the end of their section. 
     110              - included: inherited objects are mixed in with  
     111                non-inherited objects.'''), 
     112      'css': textwrap.dedent( 
     113          'The following built-in CSS stylesheets are available:\n' + 
     114          '\n'.join(['  %10s: %s' % (key, descr) 
     115                     for (key, (sheet, descr)) 
     116                     in CSS_STYLESHEETS.items()])), 
     117      #'checks': textwrap.dedent('''\ 
     118      # 
     119      #    '''), 
     120      } 
     121           
     122   
     123  HELP_TOPICS['topics'] = wordwrap( 
     124      'Epydoc can provide additional help for the following topics: ' + 
     125      ', '.join(['%r' % topic for topic in HELP_TOPICS.keys()])) 
     126       
     127  ###################################################################### 
     128  #{ Argument & Config File Parsing 
     129  ###################################################################### 
     130   
     131  OPTION_DEFAULTS = dict( 
     132      action="html", show_frames=True, docformat=DEFAULT_DOCFORMAT,  
     133      show_private=True, show_imports=False, inheritance="listed", 
     134      verbose=0, quiet=0, load_pickle=False, parse=True, introspect=True, 
     135      debug=epydoc.DEBUG, profile=False, graphs=[], 
     136      list_classes_separately=False, graph_font=None, graph_font_size=None, 
     137      include_source_code=True, pstat_files=[], simple_term=False, fail_on=None, 
     138      exclude=[], exclude_parse=[], exclude_introspect=[], 
     139      external_api=[], external_api_file=[], external_api_root=[], 
     140      redundant_details=False, src_code_tab_width=8) 
     141   
    
    142 -def parse_arguments():
    143 # Construct the option parser. 144 usage = '%prog [ACTION] [options] NAMES...' 145 version = "Epydoc, version %s" % epydoc.__version__ 146 optparser = OptionParser(usage=usage, add_help_option=False) 147 148 optparser.add_option('--config', 149 action='append', dest="configfiles", metavar='FILE', 150 help=("A configuration file, specifying additional OPTIONS " 151 "and/or NAMES. This option may be repeated.")) 152 153 optparser.add_option("--output", "-o", 154 dest="target", metavar="PATH", 155 help="The output directory. If PATH does not exist, then " 156 "it will be created.") 157 158 optparser.add_option("--quiet", "-q", 159 action="count", dest="quiet", 160 help="Decrease the verbosity.") 161 162 optparser.add_option("--verbose", "-v", 163 action="count", dest="verbose", 164 help="Increase the verbosity.") 165 166 optparser.add_option("--debug", 167 action="store_true", dest="debug", 168 help="Show full tracebacks for internal errors.") 169 170 optparser.add_option("--simple-term", 171 action="store_true", dest="simple_term", 172 help="Do not try to use color or cursor control when displaying " 173 "the progress bar, warnings, or errors.") 174 175 176 action_group = OptionGroup(optparser, 'Actions') 177 optparser.add_option_group(action_group) 178 179 action_group.add_option("--html", 180 action="store_const", dest="action", const="html", 181 help="Write HTML output.") 182 183 action_group.add_option("--text", 184 action="store_const", dest="action", const="text", 185 help="Write plaintext output. (not implemented yet)") 186 187 action_group.add_option("--latex", 188 action="store_const", dest="action", const="latex", 189 help="Write LaTeX output.") 190 191 action_group.add_option("--dvi", 192 action="store_const", dest="action", const="dvi", 193 help="Write DVI output.") 194 195 action_group.add_option("--ps", 196 action="store_const", dest="action", const="ps", 197 help="Write Postscript output.") 198 199 action_group.add_option("--pdf", 200 action="store_const", dest="action", const="pdf", 201 help="Write PDF output.") 202 203 action_group.add_option("--check", 204 action="store_const", dest="action", const="check", 205 help="Check completeness of docs.") 206 207 action_group.add_option("--pickle", 208 action="store_const", dest="action", const="pickle", 209 help="Write the documentation to a pickle file.") 210 211 # Provide our own --help and --version options. 212 action_group.add_option("--version", 213 action="store_const", dest="action", const="version", 214 help="Show epydoc's version number and exit.") 215 216 action_group.add_option("-h", "--help", 217 action="store_const", dest="action", const="help", 218 help="Show this message and exit. For help on specific " 219 "topics, use \"--help TOPIC\". Use \"--help topics\" for a " 220 "list of available help topics") 221 222 223 generation_group = OptionGroup(optparser, 'Generation Options') 224 optparser.add_option_group(generation_group) 225 226 generation_group.add_option("--docformat", 227 dest="docformat", metavar="NAME", 228 help="The default markup language for docstrings. Defaults " 229 "to \"%s\"." % DEFAULT_DOCFORMAT) 230 231 generation_group.add_option("--parse-only", 232 action="store_false", dest="introspect", 233 help="Get all information from parsing (don't introspect)") 234 235 generation_group.add_option("--introspect-only", 236 action="store_false", dest="parse", 237 help="Get all information from introspecting (don't parse)") 238 239 generation_group.add_option("--exclude", 240 dest="exclude", metavar="PATTERN", action="append", 241 help="Exclude modules whose dotted name matches " 242 "the regular expression PATTERN") 243 244 generation_group.add_option("--exclude-introspect", 245 dest="exclude_introspect", metavar="PATTERN", action="append", 246 help="Exclude introspection of modules whose dotted name matches " 247 "the regular expression PATTERN") 248 249 generation_group.add_option("--exclude-parse", 250 dest="exclude_parse", metavar="PATTERN", action="append", 251 help="Exclude parsing of modules whose dotted name matches " 252 "the regular expression PATTERN") 253 254 generation_group.add_option("--inheritance", 255 dest="inheritance", metavar="STYLE", 256 help="The format for showing inheritance objects. STYLE " 257 "should be one of: %s." % ', '.join(INHERITANCE_STYLES)) 258 259 generation_group.add_option("--show-private", 260 action="store_true", dest="show_private", 261 help="Include private variables in the output. (default)") 262 263 generation_group.add_option("--no-private", 264 action="store_false", dest="show_private", 265 help="Do not include private variables in the output.") 266 267 generation_group.add_option("--show-imports", 268 action="store_true", dest="show_imports", 269 help="List each module's imports.") 270 271 generation_group.add_option("--no-imports", 272 action="store_false", dest="show_imports", 273 help="Do not list each module's imports. (default)") 274 275 generation_group.add_option('--show-sourcecode', 276 action='store_true', dest='include_source_code', 277 help=("Include source code with syntax highlighting in the " 278 "HTML output. (default)")) 279 280 generation_group.add_option('--no-sourcecode', 281 action='store_false', dest='include_source_code', 282 help=("Do not include source code with syntax highlighting in the " 283 "HTML output.")) 284 285 generation_group.add_option('--include-log', 286 action='store_true', dest='include_log', 287 help=("Include a page with the process log (epydoc-log.html)")) 288 289 generation_group.add_option( 290 '--redundant-details', 291 action='store_true', dest='redundant_details', 292 help=("Include values in the details lists even if all info " 293 "about them is already provided by the summary table.")) 294 295 output_group = OptionGroup(optparser, 'Output Options') 296 optparser.add_option_group(output_group) 297 298 output_group.add_option("--name", "-n", 299 dest="prj_name", metavar="NAME", 300 help="The documented project's name (for the navigation bar).") 301 302 output_group.add_option("--css", "-c", 303 dest="css", metavar="STYLESHEET", 304 help="The CSS stylesheet. STYLESHEET can be either a " 305 "builtin stylesheet or the name of a CSS file.") 306 307 output_group.add_option("--url", "-u", 308 dest="prj_url", metavar="URL", 309 help="The documented project's URL (for the navigation bar).") 310 311 output_group.add_option("--navlink", 312 dest="prj_link", metavar="HTML", 313 help="HTML code for a navigation link to place in the " 314 "navigation bar.") 315 316 output_group.add_option("--top", 317 dest="top_page", metavar="PAGE", 318 help="The \"top\" page for the HTML documentation. PAGE can " 319 "be a URL, the name of a module or class, or one of the " 320 "special names \"trees.html\", \"indices.html\", or \"help.html\"") 321 322 output_group.add_option("--help-file", 323 dest="help_file", metavar="FILE", 324 help="An alternate help file. FILE should contain the body " 325 "of an HTML file -- navigation bars will be added to it.") 326 327 output_group.add_option("--show-frames", 328 action="store_true", dest="show_frames", 329 help="Include frames in the HTML output. (default)") 330 331 output_group.add_option("--no-frames", 332 action="store_false", dest="show_frames", 333 help="Do not include frames in the HTML output.") 334 335 output_group.add_option('--separate-classes', 336 action='store_true', dest='list_classes_separately', 337 help=("When generating LaTeX or PDF output, list each class in " 338 "its own section, instead of listing them under their " 339 "containing module.")) 340 341 output_group.add_option('--src-code-tab-width', 342 action='store', type='int', dest='src_code_tab_width', 343 help=("When generating HTML output, sets the number of spaces " 344 "each tab in source code listings is replaced with.")) 345 346 # The group of external API options. 347 # Skip if the module couldn't be imported (usually missing docutils) 348 if xlink is not None: 349 link_group = OptionGroup(optparser, 350 xlink.ApiLinkReader.settings_spec[0]) 351 optparser.add_option_group(link_group) 352 353 for help, names, opts in xlink.ApiLinkReader.settings_spec[2]: 354 opts = opts.copy() 355 opts['help'] = help 356 link_group.add_option(*names, **opts) 357 358 graph_group = OptionGroup(optparser, 'Graph Options') 359 optparser.add_option_group(graph_group) 360 361 graph_group.add_option('--graph', 362 action='append', dest='graphs', metavar='GRAPHTYPE', 363 help=("Include graphs of type GRAPHTYPE in the generated output. " 364 "Graphs are generated using the Graphviz dot executable. " 365 "If this executable is not on the path, then use --dotpath " 366 "to specify its location. This option may be repeated to " 367 "include multiple graph types in the output. GRAPHTYPE " 368 "should be one of: all, %s." % ', '.join(GRAPH_TYPES))) 369 370 graph_group.add_option("--dotpath", 371 dest="dotpath", metavar='PATH', 372 help="The path to the Graphviz 'dot' executable.") 373 374 graph_group.add_option('--graph-font', 375 dest='graph_font', metavar='FONT', 376 help=("Specify the font used to generate Graphviz graphs. (e.g., " 377 "helvetica or times).")) 378 379 graph_group.add_option('--graph-font-size', 380 dest='graph_font_size', metavar='SIZE', 381 help=("Specify the font size used to generate Graphviz graphs, " 382 "in points.")) 383 384 graph_group.add_option('--pstat', 385 action='append', dest='pstat_files', metavar='FILE', 386 help="A pstat output file, to be used in generating call graphs.") 387 388 # this option is for developers, not users. 389 graph_group.add_option("--profile-epydoc", 390 action="store_true", dest="profile", 391 help=SUPPRESS_HELP or 392 ("Run the hotshot profiler on epydoc itself. Output " 393 "will be written to profile.out.")) 394 395 396 return_group = OptionGroup(optparser, 'Return Value Options') 397 optparser.add_option_group(return_group) 398 399 return_group.add_option("--fail-on-error", 400 action="store_const", dest="fail_on", const=log.ERROR, 401 help="Return a non-zero exit status, indicating failure, if any " 402 "errors are encountered.") 403 404 return_group.add_option("--fail-on-warning", 405 action="store_const", dest="fail_on", const=log.WARNING, 406 help="Return a non-zero exit status, indicating failure, if any " 407 "errors or warnings are encountered (not including docstring " 408 "warnings).") 409 410 return_group.add_option("--fail-on-docstring-warning", 411 action="store_const", dest="fail_on", const=log.DOCSTRING_WARNING, 412 help="Return a non-zero exit status, indicating failure, if any " 413 "errors or warnings are encountered (including docstring " 414 "warnings).") 415 416 # Set the option parser's defaults. 417 optparser.set_defaults(**OPTION_DEFAULTS) 418 419 # Parse the arguments. 420 options, names = optparser.parse_args() 421 422 # Print help message, if requested. We also provide support for 423 # --help [topic] 424 if options.action == 'help': 425 names = set([n.lower() for n in names]) 426 for (topic, msg) in HELP_TOPICS.items(): 427 if topic.lower() in names: 428 print '\n' + msg.rstrip() + '\n' 429 sys.exit(0) 430 optparser.print_help() 431 sys.exit(0) 432 433 # Print version message, if requested. 434 if options.action == 'version': 435 print version 436 sys.exit(0) 437 438 # Process any config files. 439 if options.configfiles: 440 try: 441 parse_configfiles(options.configfiles, options, names) 442 except (KeyboardInterrupt,SystemExit): raise 443 except Exception, e: 444 if len(options.configfiles) == 1: 445 cf_name = 'config file %s' % options.configfiles[0] 446 else: 447 cf_name = 'config files %s' % ', '.join(options.configfiles) 448 optparser.error('Error reading %s:\n %s' % (cf_name, e)) 449 450 # Check if the input file is a pickle file. 451 for name in names: 452 if name.endswith('.pickle'): 453 if len(names) != 1: 454 optparser.error("When a pickle file is specified, no other " 455 "input files may be specified.") 456 options.load_pickle = True 457 458 # Check to make sure all options are valid. 459 if len(names) == 0: 460 optparser.error("No names specified.") 461 462 # perform shell expansion. 463 for i, name in reversed(list(enumerate(names[:]))): 464 if '?' in name or '*' in name: 465 names[i:i+1] = glob(name) 466 467 if options.inheritance not in INHERITANCE_STYLES: 468 optparser.error("Bad inheritance style. Valid options are " + 469 ",".join(INHERITANCE_STYLES)) 470 if not options.parse and not options.introspect: 471 optparser.error("Invalid option combination: --parse-only " 472 "and --introspect-only.") 473 if options.action == 'text' and len(names) > 1: 474 optparser.error("--text option takes only one name.") 475 476 # Check the list of requested graph types to make sure they're 477 # acceptable. 478 options.graphs = [graph_type.lower() for graph_type in options.graphs] 479 for graph_type in options.graphs: 480 if graph_type == 'callgraph' and not options.pstat_files: 481 optparser.error('"callgraph" graph type may only be used if ' 482 'one or more pstat files are specified.') 483 # If it's 'all', then add everything (but don't add callgraph if 484 # we don't have any profiling info to base them on). 485 if graph_type == 'all': 486 if options.pstat_files: 487 options.graphs = GRAPH_TYPES 488 else: 489 options.graphs = [g for g in GRAPH_TYPES if g != 'callgraph'] 490 break 491 elif graph_type not in GRAPH_TYPES: 492 optparser.error("Invalid graph type %s." % graph_type) 493 494 # Calculate verbosity. 495 verbosity = getattr(options, 'verbosity', 0) 496 options.verbosity = verbosity + options.verbose - options.quiet 497 498 # The target default depends on the action. 499 if options.target is None: 500 options.target = options.action 501 502 # Return parsed args. 503 options.names = names 504 return options, names
    505
    506 -def parse_configfiles(configfiles, options, names):
    507 configparser = ConfigParser.ConfigParser() 508 # ConfigParser.read() silently ignores errors, so open the files 509 # manually (since we want to notify the user of any errors). 510 for configfile in configfiles: 511 fp = open(configfile, 'r') # may raise IOError. 512 configparser.readfp(fp, configfile) 513 fp.close() 514 for optname in configparser.options('epydoc'): 515 val = configparser.get('epydoc', optname, vars=os.environ).strip() 516 optname = optname.lower().strip() 517 518 if optname in ('modules', 'objects', 'values', 519 'module', 'object', 'value'): 520 names.extend(_str_to_list(val)) 521 elif optname == 'target': 522 options.target = val 523 elif optname == 'output': 524 if val.lower() not in ACTIONS: 525 raise ValueError('"%s" expected one of: %s' % 526 (optname, ', '.join(ACTIONS))) 527 options.action = val.lower() 528 elif optname == 'verbosity': 529 options.verbosity = _str_to_int(val, optname) 530 elif optname == 'debug': 531 options.debug = _str_to_bool(val, optname) 532 elif optname in ('simple-term', 'simple_term'): 533 options.simple_term = _str_to_bool(val, optname) 534 535 # Generation options 536 elif optname == 'docformat': 537 options.docformat = val 538 elif optname == 'parse': 539 options.parse = _str_to_bool(val, optname) 540 elif optname == 'introspect': 541 options.introspect = _str_to_bool(val, optname) 542 elif optname == 'exclude': 543 options.exclude.extend(_str_to_list(val)) 544 elif optname in ('exclude-parse', 'exclude_parse'): 545 options.exclude_parse.extend(_str_to_list(val)) 546 elif optname in ('exclude-introspect', 'exclude_introspect'): 547 options.exclude_introspect.extend(_str_to_list(val)) 548 elif optname == 'inheritance': 549 if val.lower() not in INHERITANCE_STYLES: 550 raise ValueError('"%s" expected one of: %s.' % 551 (optname, ', '.join(INHERITANCE_STYLES))) 552 options.inheritance = val.lower() 553 elif optname =='private': 554 options.show_private = _str_to_bool(val, optname) 555 elif optname =='imports': 556 options.show_imports = _str_to_bool(val, optname) 557 elif optname == 'sourcecode': 558 options.include_source_code = _str_to_bool(val, optname) 559 elif optname in ('include-log', 'include_log'): 560 options.include_log = _str_to_bool(val, optname) 561 elif optname in ('redundant-details', 'redundant_details'): 562 options.redundant_details = _str_to_bool(val, optname) 563 564 # Output options 565 elif optname == 'name': 566 options.prj_name = val 567 elif optname == 'css': 568 options.css = val 569 elif optname == 'url': 570 options.prj_url = val 571 elif optname == 'link': 572 options.prj_link = val 573 elif optname == 'top': 574 options.top_page = val 575 elif optname == 'help': 576 options.help_file = val 577 elif optname =='frames': 578 options.show_frames = _str_to_bool(val, optname) 579 elif optname in ('separate-classes', 'separate_classes'): 580 options.list_classes_separately = _str_to_bool(val, optname) 581 elif optname in ('src-code-tab-width', 'src_code_tab_width'): 582 options.src_code_tab_width = _str_to_int(val, optname) 583 584 # External API 585 elif optname in ('external-api', 'external_api'): 586 options.external_api.extend(_str_to_list(val)) 587 elif optname in ('external-api-file', 'external_api_file'): 588 options.external_api_file.extend(_str_to_list(val)) 589 elif optname in ('external-api-root', 'external_api_root'): 590 options.external_api_root.extend(_str_to_list(val)) 591 592 # Graph options 593 elif optname == 'graph': 594 graphtypes = _str_to_list(val) 595 for graphtype in graphtypes: 596 if graphtype not in GRAPH_TYPES + ('all',): 597 raise ValueError('"%s" expected one of: all, %s.' % 598 (optname, ', '.join(GRAPH_TYPES))) 599 options.graphs.extend(graphtypes) 600 elif optname == 'dotpath': 601 options.dotpath = val 602 elif optname in ('graph-font', 'graph_font'): 603 options.graph_font = val 604 elif optname in ('graph-font-size', 'graph_font_size'): 605 options.graph_font_size = _str_to_int(val, optname) 606 elif optname == 'pstat': 607 options.pstat_files.extend(_str_to_list(val)) 608 609 # Return value options 610 elif optname in ('failon', 'fail-on', 'fail_on'): 611 if val.lower().strip() in ('error', 'errors'): 612 options.fail_on = log.ERROR 613 elif val.lower().strip() in ('warning', 'warnings'): 614 options.fail_on = log.WARNING 615 elif val.lower().strip() in ('docstring_warning', 616 'docstring_warnings'): 617 options.fail_on = log.DOCSTRING_WARNING 618 else: 619 raise ValueError("%r expected one of: error, warning, " 620 "docstring_warning" % optname) 621 else: 622 raise ValueError('Unknown option %s' % optname)
    623
    624 -def _str_to_bool(val, optname):
    625 if val.lower() in ('0', 'no', 'false', 'n', 'f', 'hide'): 626 return False 627 elif val.lower() in ('1', 'yes', 'true', 'y', 't', 'show'): 628 return True 629 else: 630 raise ValueError('"%s" option expected a boolean' % optname)
    631
    632 -def _str_to_int(val, optname):
    633 try: 634 return int(val) 635 except ValueError: 636 raise ValueError('"%s" option expected an int' % optname)
    637
    638 -def _str_to_list(val):
    639 return val.replace(',', ' ').split()
    640 641 ###################################################################### 642 #{ Interface 643 ###################################################################### 644
    645 -def main(options, names):
    646 # Set the debug flag, if '--debug' was specified. 647 if options.debug: 648 epydoc.DEBUG = True 649 650 ## [XX] Did this serve a purpose? Commenting out for now: 651 #if options.action == 'text': 652 # if options.parse and options.introspect: 653 # options.parse = False 654 655 # Set up the logger 656 if options.simple_term: 657 TerminalController.FORCE_SIMPLE_TERM = True 658 if options.action == 'text': 659 logger = None # no logger for text output. 660 elif options.verbosity > 1: 661 logger = ConsoleLogger(options.verbosity) 662 log.register_logger(logger) 663 else: 664 # Each number is a rough approximation of how long we spend on 665 # that task, used to divide up the unified progress bar. 666 stages = [40, # Building documentation 667 7, # Merging parsed & introspected information 668 1, # Linking imported variables 669 3, # Indexing documentation 670 1, # Checking for overridden methods 671 30, # Parsing Docstrings 672 1, # Inheriting documentation 673 2] # Sorting & Grouping 674 if options.load_pickle: 675 stages = [30] # Loading pickled documentation 676 if options.action == 'html': stages += [100] 677 elif options.action == 'text': stages += [30] 678 elif options.action == 'latex': stages += [60] 679 elif options.action == 'dvi': stages += [60,30] 680 elif options.action == 'ps': stages += [60,40] 681 elif options.action == 'pdf': stages += [60,50] 682 elif options.action == 'check': stages += [10] 683 elif options.action == 'pickle': stages += [10] 684 else: raise ValueError, '%r not supported' % options.action 685 if options.parse and not options.introspect: 686 del stages[1] # no merging 687 if options.introspect and not options.parse: 688 del stages[1:3] # no merging or linking 689 logger = UnifiedProgressConsoleLogger(options.verbosity, stages) 690 log.register_logger(logger) 691 692 # check the output directory. 693 if options.action not in ('text', 'check', 'pickle'): 694 if os.path.exists(options.target): 695 if not os.path.isdir(options.target): 696 log.error("%s is not a directory" % options.target) 697 sys.exit(1) 698 699 if options.include_log: 700 if options.action == 'html': 701 if not os.path.exists(options.target): 702 os.mkdir(options.target) 703 log.register_logger(HTMLLogger(options.target, options)) 704 else: 705 log.warning("--include-log requires --html") 706 707 # Set the default docformat 708 from epydoc import docstringparser 709 docstringparser.DEFAULT_DOCFORMAT = options.docformat 710 711 # Configure the external API linking 712 if xlink is not None: 713 try: 714 xlink.ApiLinkReader.read_configuration(options, problematic=False) 715 except Exception, exc: 716 log.error("Error while configuring external API linking: %s: %s" 717 % (exc.__class__.__name__, exc)) 718 719 # Set the dot path 720 if options.dotpath: 721 from epydoc.docwriter import dotgraph 722 dotgraph.DOT_COMMAND = options.dotpath 723 724 # Set the default graph font & size 725 if options.graph_font: 726 from epydoc.docwriter import dotgraph 727 fontname = options.graph_font 728 dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontname'] = fontname 729 dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontname'] = fontname 730 if options.graph_font_size: 731 from epydoc.docwriter import dotgraph 732 fontsize = options.graph_font_size 733 dotgraph.DotGraph.DEFAULT_NODE_DEFAULTS['fontsize'] = fontsize 734 dotgraph.DotGraph.DEFAULT_EDGE_DEFAULTS['fontsize'] = fontsize 735 736 # If the input name is a pickle file, then read the docindex that 737 # it contains. Otherwise, build the docs for the input names. 738 if options.load_pickle: 739 assert len(names) == 1 740 log.start_progress('Deserializing') 741 log.progress(0.1, 'Loading %r' % names[0]) 742 t0 = time.time() 743 unpickler = pickle.Unpickler(open(names[0], 'rb')) 744 unpickler.persistent_load = pickle_persistent_load 745 docindex = unpickler.load() 746 log.debug('deserialization time: %.1f sec' % (time.time()-t0)) 747 log.end_progress() 748 else: 749 # Build docs for the named values. 750 from epydoc.docbuilder import build_doc_index 751 exclude_parse = '|'.join(options.exclude_parse+options.exclude) 752 exclude_introspect = '|'.join(options.exclude_introspect+ 753 options.exclude) 754 docindex = build_doc_index(names, options.introspect, options.parse, 755 add_submodules=(options.action!='text'), 756 exclude_introspect=exclude_introspect, 757 exclude_parse=exclude_parse) 758 759 if docindex is None: 760 if log.ERROR in logger.reported_message_levels: 761 sys.exit(1) 762 else: 763 return # docbuilder already logged an error. 764 765 # Load profile information, if it was given. 766 if options.pstat_files: 767 try: import pstats 768 except ImportError: 769 log.error("Could not import pstats -- ignoring pstat files.") 770 try: 771 profile_stats = pstats.Stats(options.pstat_files[0]) 772 for filename in options.pstat_files[1:]: 773 profile_stats.add(filename) 774 except KeyboardInterrupt: raise 775 except Exception, e: 776 log.error("Error reading pstat file: %s" % e) 777 profile_stats = None 778 if profile_stats is not None: 779 docindex.read_profiling_info(profile_stats) 780 781 # Perform the specified action. 782 if options.action == 'html': 783 write_html(docindex, options) 784 elif options.action in ('latex', 'dvi', 'ps', 'pdf'): 785 write_latex(docindex, options, options.action) 786 elif options.action == 'text': 787 write_text(docindex, options) 788 elif options.action == 'check': 789 check_docs(docindex, options) 790 elif options.action == 'pickle': 791 write_pickle(docindex, options) 792 else: 793 print >>sys.stderr, '\nUnsupported action %s!' % options.action 794 795 # If we suppressed docstring warnings, then let the user know. 796 if logger is not None and logger.suppressed_docstring_warning: 797 if logger.suppressed_docstring_warning == 1: 798 prefix = '1 markup error was found' 799 else: 800 prefix = ('%d markup errors were found' % 801 logger.suppressed_docstring_warning) 802 log.warning("%s while processing docstrings. Use the verbose " 803 "switch (-v) to display markup errors." % prefix) 804 805 # Basic timing breakdown: 806 if options.verbosity >= 2 and logger is not None: 807 logger.print_times() 808 809 # If we encountered any message types that we were requested to 810 # fail on, then exit with status 2. 811 if options.fail_on is not None: 812 max_reported_message_level = max(logger.reported_message_levels) 813 if max_reported_message_level >= options.fail_on: 814 sys.exit(2)
    815
    816 -def write_html(docindex, options):
    817 from epydoc.docwriter.html import HTMLWriter 818 html_writer = HTMLWriter(docindex, **options.__dict__) 819 if options.verbose > 0: 820 log.start_progress('Writing HTML docs to %r' % options.target) 821 else: 822 log.start_progress('Writing HTML docs') 823 html_writer.write(options.target) 824 log.end_progress()
    825
    826 -def write_pickle(docindex, options):
    827 """Helper for writing output to a pickle file, which can then be 828 read in at a later time. But loading the pickle is only marginally 829 faster than building the docs from scratch, so this has pretty 830 limited application.""" 831 if options.target == 'pickle': 832 options.target = 'api.pickle' 833 elif not options.target.endswith('.pickle'): 834 options.target += '.pickle' 835 836 log.start_progress('Serializing output') 837 log.progress(0.2, 'Writing %r' % options.target) 838 outfile = open(options.target, 'wb') 839 pickler = pickle.Pickler(outfile, protocol=0) 840 pickler.persistent_id = pickle_persistent_id 841 pickler.dump(docindex) 842 outfile.close() 843 log.end_progress()
    844
    845 -def pickle_persistent_id(obj):
    846 """Helper for pickling, which allows us to save and restore UNKNOWN, 847 which is required to be identical to apidoc.UNKNOWN.""" 848 if obj is UNKNOWN: return 'UNKNOWN' 849 else: return None
    850
    851 -def pickle_persistent_load(identifier):
    852 """Helper for pickling, which allows us to save and restore UNKNOWN, 853 which is required to be identical to apidoc.UNKNOWN.""" 854 if identifier == 'UNKNOWN': return UNKNOWN 855 else: raise pickle.UnpicklingError, 'Invalid persistent id'
    856 857 _RERUN_LATEX_RE = re.compile(r'(?im)^LaTeX\s+Warning:\s+Label\(s\)\s+may' 858 r'\s+have\s+changed.\s+Rerun') 859
    860 -def write_latex(docindex, options, format):
    861 from epydoc.docwriter.latex import LatexWriter 862 latex_writer = LatexWriter(docindex, **options.__dict__) 863 log.start_progress('Writing LaTeX docs') 864 latex_writer.write(options.target) 865 log.end_progress() 866 # If we're just generating the latex, and not any output format, 867 # then we're done. 868 if format == 'latex': return 869 870 if format == 'dvi': steps = 4 871 elif format == 'ps': steps = 5 872 elif format == 'pdf': steps = 6 873 874 log.start_progress('Processing LaTeX docs') 875 oldpath = os.path.abspath(os.curdir) 876 running = None # keep track of what we're doing. 877 try: 878 try: 879 os.chdir(options.target) 880 881 # Clear any old files out of the way. 882 for ext in 'tex aux log out idx ilg toc ind'.split(): 883 if os.path.exists('apidoc.%s' % ext): 884 os.remove('apidoc.%s' % ext) 885 886 # The first pass generates index files. 887 running = 'latex' 888 log.progress(0./steps, 'LaTeX: First pass') 889 run_subprocess('latex api.tex') 890 891 # Build the index. 892 running = 'makeindex' 893 log.progress(1./steps, 'LaTeX: Build index') 894 run_subprocess('makeindex api.idx') 895 896 # The second pass generates our output. 897 running = 'latex' 898 log.progress(2./steps, 'LaTeX: Second pass') 899 out, err = run_subprocess('latex api.tex') 900 901 # The third pass is only necessary if the second pass 902 # changed what page some things are on. 903 running = 'latex' 904 if _RERUN_LATEX_RE.match(out): 905 log.progress(3./steps, 'LaTeX: Third pass') 906 out, err = run_subprocess('latex api.tex') 907 908 # A fourth path should (almost?) never be necessary. 909 running = 'latex' 910 if _RERUN_LATEX_RE.match(out): 911 log.progress(3./steps, 'LaTeX: Fourth pass') 912 run_subprocess('latex api.tex') 913 914 # If requested, convert to postscript. 915 if format in ('ps', 'pdf'): 916 running = 'dvips' 917 log.progress(4./steps, 'dvips') 918 run_subprocess('dvips api.dvi -o api.ps -G0 -Ppdf') 919 920 # If requested, convert to pdf. 921 if format in ('pdf'): 922 running = 'ps2pdf' 923 log.progress(5./steps, 'ps2pdf') 924 run_subprocess( 925 'ps2pdf -sPAPERSIZE#letter -dMaxSubsetPct#100 ' 926 '-dSubsetFonts#true -dCompatibilityLevel#1.2 ' 927 '-dEmbedAllFonts#true api.ps api.pdf') 928 except RunSubprocessError, e: 929 if running == 'latex': 930 e.out = re.sub(r'(?sm)\A.*?!( LaTeX Error:)?', r'', e.out) 931 e.out = re.sub(r'(?sm)\s*Type X to quit.*', '', e.out) 932 e.out = re.sub(r'(?sm)^! Emergency stop.*', '', e.out) 933 log.error("%s failed: %s" % (running, (e.out+e.err).lstrip())) 934 except OSError, e: 935 log.error("%s failed: %s" % (running, e)) 936 finally: 937 os.chdir(oldpath) 938 log.end_progress()
    939
    940 -def write_text(docindex, options):
    941 log.start_progress('Writing output') 942 from epydoc.docwriter.plaintext import PlaintextWriter 943 plaintext_writer = PlaintextWriter() 944 s = '' 945 for apidoc in docindex.root: 946 s += plaintext_writer.write(apidoc) 947 log.end_progress() 948 if isinstance(s, unicode): 949 s = s.encode('ascii', 'backslashreplace') 950 print s
    951
    952 -def check_docs(docindex, options):
    953 from epydoc.checker import DocChecker 954 DocChecker(docindex).check()
    955
    956 -def cli():
    957 # Parse command-line arguments. 958 options, names = parse_arguments() 959 960 try: 961 try: 962 if options.profile: 963 _profile() 964 else: 965 main(options, names) 966 finally: 967 log.close() 968 except SystemExit: 969 raise 970 except KeyboardInterrupt: 971 print '\n\n' 972 print >>sys.stderr, 'Keyboard interrupt.' 973 except: 974 if options.debug: raise 975 print '\n\n' 976 exc_info = sys.exc_info() 977 if isinstance(exc_info[0], basestring): e = exc_info[0] 978 else: e = exc_info[1] 979 print >>sys.stderr, ('\nUNEXPECTED ERROR:\n' 980 '%s\n' % (str(e) or e.__class__.__name__)) 981 print >>sys.stderr, 'Use --debug to see trace information.' 982 sys.exit(3)
    983
    984 -def _profile():
    985 # Hotshot profiler. 986 if PROFILER == 'hotshot': 987 try: import hotshot, hotshot.stats 988 except ImportError: 989 print >>sys.stderr, "Could not import profile module!" 990 return 991 try: 992 prof = hotshot.Profile('hotshot.out') 993 prof = prof.runctx('main(*parse_arguments())', globals(), {}) 994 except SystemExit: 995 pass 996 prof.close() 997 # Convert profile.hotshot -> profile.out 998 print 'Consolidating hotshot profiling info...' 999 hotshot.stats.load('hotshot.out').dump_stats('profile.out') 1000 1001 # Standard 'profile' profiler. 1002 elif PROFILER == 'profile': 1003 # cProfile module was added in Python 2.5 -- use it if its' 1004 # available, since it's faster. 1005 try: from cProfile import Profile 1006 except ImportError: 1007 try: from profile import Profile 1008 except ImportError: 1009 print >>sys.stderr, "Could not import profile module!" 1010 return 1011 1012 # There was a bug in Python 2.4's profiler. Check if it's 1013 # present, and if so, fix it. (Bug was fixed in 2.4maint: 1014 # <http://mail.python.org/pipermail/python-checkins/ 1015 # 2005-September/047099.html>) 1016 if (hasattr(Profile, 'dispatch') and 1017 Profile.dispatch['c_exception'] is 1018 Profile.trace_dispatch_exception.im_func): 1019 trace_dispatch_return = Profile.trace_dispatch_return.im_func 1020 Profile.dispatch['c_exception'] = trace_dispatch_return 1021 try: 1022 prof = Profile() 1023 prof = prof.runctx('main(*parse_arguments())', globals(), {}) 1024 except SystemExit: 1025 pass 1026 prof.dump_stats('profile.out') 1027 1028 else: 1029 print >>sys.stderr, 'Unknown profiler %s' % PROFILER 1030 return
    1031 1032 ###################################################################### 1033 #{ Logging 1034 ###################################################################### 1035
    1036 -class TerminalController:
    1037 """ 1038 A class that can be used to portably generate formatted output to 1039 a terminal. See 1040 U{http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116} 1041 for documentation. (This is a somewhat stripped-down version.) 1042 """ 1043 BOL = '' #: Move the cursor to the beginning of the line 1044 UP = '' #: Move the cursor up one line 1045 DOWN = '' #: Move the cursor down one line 1046 LEFT = '' #: Move the cursor left one char 1047 RIGHT = '' #: Move the cursor right one char 1048 CLEAR_EOL = '' #: Clear to the end of the line. 1049 CLEAR_LINE = '' #: Clear the current line; cursor to BOL. 1050 BOLD = '' #: Turn on bold mode 1051 NORMAL = '' #: Turn off all modes 1052 COLS = 75 #: Width of the terminal (default to 75) 1053 BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = '' 1054 1055 _STRING_CAPABILITIES = """ 1056 BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1 1057 CLEAR_EOL=el BOLD=bold UNDERLINE=smul NORMAL=sgr0""".split() 1058 _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split() 1059 _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split() 1060 1061 #: If this is set to true, then new TerminalControllers will 1062 #: assume that the terminal is not capable of doing manipulation 1063 #: of any kind. 1064 FORCE_SIMPLE_TERM = False 1065
    1066 - def __init__(self, term_stream=sys.stdout):
    1067 # If the stream isn't a tty, then assume it has no capabilities. 1068 if not term_stream.isatty(): return 1069 if self.FORCE_SIMPLE_TERM: return 1070 1071 # Curses isn't available on all platforms 1072 try: import curses 1073 except: 1074 # If it's not available, then try faking enough to get a 1075 # simple progress bar. 1076 self.BOL = '\r' 1077 self.CLEAR_LINE = '\r' + ' '*self.COLS + '\r' 1078 1079 # Check the terminal type. If we fail, then assume that the 1080 # terminal has no capabilities. 1081 try: curses.setupterm() 1082 except: return 1083 1084 # Look up numeric capabilities. 1085 self.COLS = curses.tigetnum('cols') 1086 1087 # Look up string capabilities. 1088 for capability in self._STRING_CAPABILITIES: 1089 (attrib, cap_name) = capability.split('=') 1090 setattr(self, attrib, self._tigetstr(cap_name) or '') 1091 if self.BOL and self.CLEAR_EOL: 1092 self.CLEAR_LINE = self.BOL+self.CLEAR_EOL 1093 1094 # Colors 1095 set_fg = self._tigetstr('setf') 1096 if set_fg: 1097 for i,color in zip(range(len(self._COLORS)), self._COLORS): 1098 setattr(self, color, curses.tparm(set_fg, i) or '') 1099 set_fg_ansi = self._tigetstr('setaf') 1100 if set_fg_ansi: 1101 for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS): 1102 setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
    1103
    1104 - def _tigetstr(self, cap_name):
    1105 # String capabilities can include "delays" of the form "$<2>". 1106 # For any modern terminal, we should be able to just ignore 1107 # these, so strip them out. 1108 import curses 1109 cap = curses.tigetstr(cap_name) or '' 1110 return re.sub(r'\$<\d+>[/*]?', '', cap)
    1111
    1112 -class ConsoleLogger(log.Logger):
    1113 - def __init__(self, verbosity, progress_mode=None):
    1114 self._verbosity = verbosity 1115 self._progress = None 1116 self._message_blocks = [] 1117 # For ETA display: 1118 self._progress_start_time = None 1119 # For per-task times: 1120 self._task_times = [] 1121 self._progress_header = None 1122 1123 self.reported_message_levels = set() 1124 """This set contains all the message levels (WARNING, ERROR, 1125 etc) that have been reported. It is used by the options 1126 --fail-on-warning etc to determine the return value.""" 1127 1128 self.suppressed_docstring_warning = 0 1129 """This variable will be incremented once every time a 1130 docstring warning is reported tothe logger, but the verbosity 1131 level is too low for it to be displayed.""" 1132 1133 self.term = TerminalController() 1134 1135 # Set the progress bar mode. 1136 if verbosity >= 2: self._progress_mode = 'list' 1137 elif verbosity >= 0: 1138 if progress_mode is not None: 1139 self._progress_mode = progress_mode 1140 elif self.term.COLS < 15: 1141 self._progress_mode = 'simple-bar' 1142 elif self.term.BOL and self.term.CLEAR_EOL and self.term.UP: 1143 self._progress_mode = 'multiline-bar' 1144 elif self.term.BOL and self.term.CLEAR_LINE: 1145 self._progress_mode = 'bar' 1146 else: 1147 self._progress_mode = 'simple-bar' 1148 else: self._progress_mode = 'hide'
    1149
    1150 - def start_block(self, header):
    1151 self._message_blocks.append( (header, []) )
    1152
    1153 - def end_block(self):
    1154 header, messages = self._message_blocks.pop() 1155 if messages: 1156 width = self.term.COLS - 5 - 2*len(self._message_blocks) 1157 prefix = self.term.CYAN+self.term.BOLD+'| '+self.term.NORMAL 1158 divider = (self.term.CYAN+self.term.BOLD+'+'+'-'*(width-1)+ 1159 self.term.NORMAL) 1160 # Mark up the header: 1161 header = wordwrap(header, right=width-2, splitchars='\\/').rstrip() 1162 header = '\n'.join([prefix+self.term.CYAN+l+self.term.NORMAL 1163 for l in header.split('\n')]) 1164 # Construct the body: 1165 body = '' 1166 for message in messages: 1167 if message.endswith('\n'): body += message 1168 else: body += message+'\n' 1169 # Indent the body: 1170 body = '\n'.join([prefix+' '+l for l in body.split('\n')]) 1171 # Put it all together: 1172 message = divider + '\n' + header + '\n' + body + '\n' 1173 self._report(message)
    1174
    1175 - def _format(self, prefix, message, color):
    1176 """ 1177 Rewrap the message; but preserve newlines, and don't touch any 1178 lines that begin with spaces. 1179 """ 1180 lines = message.split('\n') 1181 startindex = indent = len(prefix) 1182 for i in range(len(lines)): 1183 if lines[i].startswith(' '): 1184 lines[i] = ' '*(indent-startindex) + lines[i] + '\n' 1185 else: 1186 width = self.term.COLS - 5 - 4*len(self._message_blocks) 1187 lines[i] = wordwrap(lines[i], indent, width, startindex, '\\/') 1188 startindex = 0 1189 return color+prefix+self.term.NORMAL+''.join(lines)
    1190
    1191 - def log(self, level, message):
    1192 self.reported_message_levels.add(level) 1193 if self._verbosity >= -2 and level >= log.ERROR: 1194 message = self._format(' Error: ', message, self.term.RED) 1195 elif self._verbosity >= -1 and level >= log.WARNING: 1196 message = self._format('Warning: ', message, self.term.YELLOW) 1197 elif self._verbosity >= 1 and level >= log.DOCSTRING_WARNING: 1198 message = self._format('Warning: ', message, self.term.YELLOW) 1199 elif self._verbosity >= 3 and level >= log.INFO: 1200 message = self._format(' Info: ', message, self.term.NORMAL) 1201 elif epydoc.DEBUG and level == log.DEBUG: 1202 message = self._format(' Debug: ', message, self.term.CYAN) 1203 else: 1204 if level >= log.DOCSTRING_WARNING: 1205 self.suppressed_docstring_warning += 1 1206 return 1207 1208 self._report(message)
    1209
    1210 - def _report(self, message):
    1211 if not message.endswith('\n'): message += '\n' 1212 1213 if self._message_blocks: 1214 self._message_blocks[-1][-1].append(message) 1215 else: 1216 # If we're in the middle of displaying a progress bar, 1217 # then make room for the message. 1218 if self._progress_mode == 'simple-bar': 1219 if self._progress is not None: 1220 print 1221 self._progress = None 1222 if self._progress_mode == 'bar': 1223 sys.stdout.write(self.term.CLEAR_LINE) 1224 if self._progress_mode == 'multiline-bar': 1225 sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 + 1226 self.term.CLEAR_EOL + self.term.UP*2) 1227 1228 # Display the message message. 1229 sys.stdout.write(message) 1230 sys.stdout.flush()
    1231
    1232 - def progress(self, percent, message=''):
    1233 percent = min(1.0, percent) 1234 message = '%s' % message 1235 1236 if self._progress_mode == 'list': 1237 if message: 1238 print '[%3d%%] %s' % (100*percent, message) 1239 sys.stdout.flush() 1240 1241 elif self._progress_mode == 'bar': 1242 dots = int((self.term.COLS/2-8)*percent) 1243 background = '-'*(self.term.COLS/2-8) 1244 if len(message) > self.term.COLS/2: 1245 message = message[:self.term.COLS/2-3]+'...' 1246 sys.stdout.write(self.term.CLEAR_LINE + '%3d%% '%(100*percent) + 1247 self.term.GREEN + '[' + self.term.BOLD + 1248 '='*dots + background[dots:] + self.term.NORMAL + 1249 self.term.GREEN + '] ' + self.term.NORMAL + 1250 message + self.term.BOL) 1251 sys.stdout.flush() 1252 self._progress = percent 1253 elif self._progress_mode == 'multiline-bar': 1254 dots = int((self.term.COLS-10)*percent) 1255 background = '-'*(self.term.COLS-10) 1256 1257 if len(message) > self.term.COLS-10: 1258 message = message[:self.term.COLS-10-3]+'...' 1259 else: 1260 message = message.center(self.term.COLS-10) 1261 1262 time_elapsed = time.time()-self._progress_start_time 1263 if percent > 0: 1264 time_remain = (time_elapsed / percent) * (1-percent) 1265 else: 1266 time_remain = 0 1267 1268 sys.stdout.write( 1269 # Line 1: 1270 self.term.CLEAR_EOL + ' ' + 1271 '%-8s' % self._timestr(time_elapsed) + 1272 self.term.BOLD + 'Progress:'.center(self.term.COLS-26) + 1273 self.term.NORMAL + '%8s' % self._timestr(time_remain) + '\n' + 1274 # Line 2: 1275 self.term.CLEAR_EOL + ('%3d%% ' % (100*percent)) + 1276 self.term.GREEN + '[' + self.term.BOLD + '='*dots + 1277 background[dots:] + self.term.NORMAL + self.term.GREEN + 1278 ']' + self.term.NORMAL + '\n' + 1279 # Line 3: 1280 self.term.CLEAR_EOL + ' ' + message + self.term.BOL + 1281 self.term.UP + self.term.UP) 1282 1283 sys.stdout.flush() 1284 self._progress = percent 1285 elif self._progress_mode == 'simple-bar': 1286 if self._progress is None: 1287 sys.stdout.write(' [') 1288 self._progress = 0.0 1289 dots = int((self.term.COLS-2)*percent) 1290 progress_dots = int((self.term.COLS-2)*self._progress) 1291 if dots > progress_dots: 1292 sys.stdout.write('.'*(dots-progress_dots)) 1293 sys.stdout.flush() 1294 self._progress = percent
    1295
    1296 - def _timestr(self, dt):
    1297 dt = int(dt) 1298 if dt >= 3600: 1299 return '%d:%02d:%02d' % (dt/3600, dt%3600/60, dt%60) 1300 else: 1301 return '%02d:%02d' % (dt/60, dt%60)
    1302
    1303 - def start_progress(self, header=None):
    1304 if self._progress is not None: 1305 raise ValueError 1306 self._progress = None 1307 self._progress_start_time = time.time() 1308 self._progress_header = header 1309 if self._progress_mode != 'hide' and header: 1310 print self.term.BOLD + header + self.term.NORMAL
    1311
    1312 - def end_progress(self):
    1313 self.progress(1.) 1314 if self._progress_mode == 'bar': 1315 sys.stdout.write(self.term.CLEAR_LINE) 1316 if self._progress_mode == 'multiline-bar': 1317 sys.stdout.write((self.term.CLEAR_EOL + '\n')*2 + 1318 self.term.CLEAR_EOL + self.term.UP*2) 1319 if self._progress_mode == 'simple-bar': 1320 print ']' 1321 self._progress = None 1322 self._task_times.append( (time.time()-self._progress_start_time, 1323 self._progress_header) )
    1324
    1325 - def print_times(self):
    1326 print 1327 print 'Timing summary:' 1328 total = sum([time for (time, task) in self._task_times]) 1329 max_t = max([time for (time, task) in self._task_times]) 1330 for (time, task) in self._task_times: 1331 task = task[:31] 1332 print ' %s%s %7.1fs' % (task, '.'*(35-len(task)), time), 1333 if self.term.COLS > 55: 1334 print '|'+'=' * int((self.term.COLS-53) * time / max_t) 1335 else: 1336 print 1337 print
    1338
    1339 -class UnifiedProgressConsoleLogger(ConsoleLogger):
    1340 - def __init__(self, verbosity, stages, progress_mode=None):
    1341 self.stage = 0 1342 self.stages = stages 1343 self.task = None 1344 ConsoleLogger.__init__(self, verbosity, progress_mode)
    1345
    1346 - def progress(self, percent, message=''):
    1347 #p = float(self.stage-1+percent)/self.stages 1348 i = self.stage-1 1349 p = ((sum(self.stages[:i]) + percent*self.stages[i]) / 1350 float(sum(self.stages))) 1351 1352 if message is UNKNOWN: message = None 1353 if message: message = '%s: %s' % (self.task, message) 1354 ConsoleLogger.progress(self, p, message)
    1355
    1356 - def start_progress(self, header=None):
    1357 self.task = header 1358 if self.stage == 0: 1359 ConsoleLogger.start_progress(self) 1360 self.stage += 1
    1361
    1362 - def end_progress(self):
    1363 if self.stage == len(self.stages): 1364 ConsoleLogger.end_progress(self)
    1365
    1366 - def print_times(self):
    1367 pass
    1368
    1369 -class HTMLLogger(log.Logger):
    1370 """ 1371 A logger used to generate a log of all warnings and messages to an 1372 HTML file. 1373 """ 1374 1375 FILENAME = "epydoc-log.html" 1376 HEADER = textwrap.dedent('''\ 1377 <?xml version="1.0" encoding="ascii"?> 1378 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 1379 "DTD/xhtml1-transitional.dtd"> 1380 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 1381 <head> 1382 <title>Epydoc Log</title> 1383 <link rel="stylesheet" href="epydoc.css" type="text/css" /> 1384 </head> 1385 1386 <body bgcolor="white" text="black" link="blue" vlink="#204080" 1387 alink="#204080"> 1388 <h1 class="epydoc">Epydoc Log</h1> 1389 <p class="log">Epydoc started at %s</p>''') 1390 START_BLOCK = '<div class="log-block"><h2 class="log-hdr">%s</h2>' 1391 MESSAGE = ('<div class="log-%s"><b>%s</b>: \n' 1392 '%s</div>\n') 1393 END_BLOCK = '</div>' 1394 FOOTER = "</body>\n</html>\n" 1395
    1396 - def __init__(self, directory, options):
    1397 self.start_time = time.time() 1398 self.out = open(os.path.join(directory, self.FILENAME), 'w') 1399 self.out.write(self.HEADER % time.ctime(self.start_time)) 1400 self.is_empty = True 1401 self.options = options
    1402
    1403 - def write_options(self, options):
    1404 self.out.write(self.START_BLOCK % 'Epydoc Options') 1405 msg = '<table border="0" cellpadding="0" cellspacing="0">\n' 1406 opts = [(key, getattr(options, key)) for key in dir(options) 1407 if key not in dir(optparse.Values)] 1408 opts = [(val==OPTION_DEFAULTS.get(key), key, val) 1409 for (key, val) in opts] 1410 for is_default, key, val in sorted(opts): 1411 css = is_default and 'opt-default' or 'opt-changed' 1412 msg += ('<tr valign="top" class="%s"><td valign="top">%s</td>' 1413 '<td valign="top"><tt>&nbsp;=&nbsp;</tt></td>' 1414 '<td valign="top"><tt>%s</tt></td></tr>' % 1415 (css, key, plaintext_to_html(repr(val)))) 1416 msg += '</table>\n' 1417 self.out.write('<div class="log-info">\n%s</div>\n' % msg) 1418 self.out.write(self.END_BLOCK)
    1419
    1420 - def start_block(self, header):
    1421 self.out.write(self.START_BLOCK % header)
    1422
    1423 - def end_block(self):
    1424 self.out.write(self.END_BLOCK)
    1425
    1426 - def log(self, level, message):
    1427 if message.endswith("(-v) to display markup errors."): return 1428 if level >= log.ERROR: 1429 self.out.write(self._message('error', message)) 1430 elif level >= log.WARNING: 1431 self.out.write(self._message('warning', message)) 1432 elif level >= log.DOCSTRING_WARNING: 1433 self.out.write(self._message('docstring warning', message))
    1434
    1435 - def _message(self, level, message):
    1436 self.is_empty = False 1437 message = plaintext_to_html(message) 1438 if '\n' in message: 1439 message = '<pre class="log">%s</pre>' % message 1440 hdr = ' '.join([w.capitalize() for w in level.split()]) 1441 return self.MESSAGE % (level.split()[-1], hdr, message)
    1442
    1443 - def close(self):
    1444 if self.is_empty: 1445 self.out.write('<div class="log-info">' 1446 'No warnings or errors!</div>') 1447 self.write_options(self.options) 1448 self.out.write('<p class="log">Epydoc finished at %s</p>\n' 1449 '<p class="log">(Elapsed time: %s)</p>' % 1450 (time.ctime(), self._elapsed_time())) 1451 self.out.write(self.FOOTER) 1452 self.out.close()
    1453
    1454 - def _elapsed_time(self):
    1455 secs = int(time.time()-self.start_time) 1456 if secs < 60: 1457 return '%d seconds' % secs 1458 if secs < 3600: 1459 return '%d minutes, %d seconds' % (secs/60, secs%60) 1460 else: 1461 return '%d hours, %d minutes' % (secs/3600, secs%3600)
    1462 1463 1464 ###################################################################### 1465 ## main 1466 ###################################################################### 1467 1468 if __name__ == '__main__': 1469 cli() 1470

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph.DotGraphUmlClassNode-class.html0000644000175000017500000026354010750103050030561 0ustar pronovicpronovic epydoc.docwriter.dotgraph.DotGraphUmlClassNode
    Package epydoc :: Package docwriter :: Module dotgraph :: Class DotGraphUmlClassNode
    [hide private]
    [frames] | no frames]

    Class DotGraphUmlClassNode

    source code


    A specialized dot graph node used to display ClassDocs using UML notation. The node is rendered as a table with three cells: the top cell contains the class name; the middle cell contains a list of attributes; and the bottom cell contains a list of operations:

    +-------------+
    |  ClassName  |
    +-------------+
    | x: int      |
    |     ...     |
    +-------------+
    | f(self, x)  |
    |     ...     |
    +-------------+
    

    DotGraphUmlClassNodes may be collapsed, in which case they are drawn as a simple box containing the class name:

    +-------------+
    |  ClassName  |
    +-------------+
    

    Attributes with types corresponding to documented classes can optionally be converted into edges, using link_attributes().


    To Do: Add more options? - show/hide operation signature - show/hide operation signature types - show/hide operation signature return type - show/hide attribute types - use qualifiers

    Instance Methods [hide private]
     
    __init__(self, class_doc, linker, context, collapsed=False, bgcolor='#d8ffe8', **options)
    Create a new DotGraphUmlClassNode based on the class class_doc.
    source code
    call graph 

    Inherited from DotGraphNode: __getitem__, __setitem__

        Attribute Linking
     
    link_attributes(self, nodes)
    Convert any attributes with type descriptions corresponding to documented classes to edges.
    source code
    call graph 
     
    _link_attribute(self, var, nodes)
    Helper for link_attributes(): try to convert the attribute variable var into an edge, and add that edge to self.edges.
    source code
    call graph 
     
    _add_attribute_edge(self, var, nodes, type_str, **attribs)
    Helper for link_attributes(): try to add an edge for the given attribute variable var.
    source code
    call graph 
        Helper Methods
     
    _type_descr(self, api_doc)
    Return a plaintext type description for api_doc
    source code
    call graph 
     
    _tooltip(self, var_doc)
    Return a tooltip for var_doc.
    source code
    call graph 
        Rendering
     
    _attribute_cell(self, var_doc) source code
    call graph 
     
    _operation_cell(self, var_doc) source code
    call graph 
     
    _operation_arg(self, name, default, func_doc) source code
    call graph 
     
    _qualifier_cell(self, key_label, port) source code
    call graph 
     
    _get_html_label(self) source code
    call graph 
     
    to_dotfile(self)
    Return the dot commands that should be used to render this node.
    source code
    call graph 
    Class Methods [hide private]
        Helper Methods
     
    _summary(self, api_doc)
    Return a plaintext summary for api_doc
    source code
    call graph 
    Class Variables [hide private]

    Inherited from DotGraphNode (private): _next_id

        Attribute Linking
      SIMPLE_TYPE_RE = re.compile(r'^([\w\.]+)$')
    A regular expression that matches descriptions of simple types.
      COLLECTION_TYPE_RE = re.compile(r'^(list|set|sequence|tuple|co...
    A regular expression that matches descriptions of collection types.
      MAPPING_TYPE_RE = re.compile(r'^(dict|dictionary|map|mapping) ...
    A regular expression that matches descriptions of mapping types.
      MAPPING_TO_COLLECTION_TYPE_RE = re.compile(r'^(dict|dictionary...
    A regular expression that matches descriptions of mapping types whose value type is a collection.
      OPTIONAL_TYPE_RE = re.compile(r'^(None or|optional) ([\w\.]+)$...
    A regular expression that matches descriptions of optional types.
        Rendering
      _ATTRIBUTE_CELL = '\n <TR><TD ALIGN="LEFT" HREF="%s" TOOLTI...
    args: (url, tooltip, label)
      _OPERATION_CELL = '\n <TR><TD ALIGN="LEFT" HREF="%s" TOOLTI...
    args: (url, tooltip, label)
      _QUALIFIER_CELL = '\n <TR><TD VALIGN="BOTTOM" PORT="%s" BGC...
    args: (port, bgcolor, label)
      _QUALIFIER_DIV = '\n <TR><TD VALIGN="BOTTOM" HEIGHT="10" WI...
      _LABEL = '\n <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="...
    Args: (rowspan, bgcolor, classname, attributes, operations, qualifiers)
      _COLLAPSED_LABEL = '\n <TABLE CELLBORDER="0" BGCOLOR="%s" P...
    Instance Variables [hide private]
      class_doc
    The class represented by this node.
      linker
    Used to look up URLs for classes.
      context
    The context in which the node will be drawn.
      bgcolor
    The background color of the node.
      options
    Options used to control how the node is displayed.
      collapsed
    If true, then draw this node as a simple box.
      attributes
    The list of VariableDocs for attributes
      operations
    The list of VariableDocs for operations
      qualifiers
    List of (key_label, port) tuples.
      edges
    List of edges used to represent this node's attributes.
    Method Details [hide private]

    __init__(self, class_doc, linker, context, collapsed=False, bgcolor='#d8ffe8', **options)
    (Constructor)

    source code 
    call graph 
    Create a new DotGraphUmlClassNode based on the class class_doc.
    Parameters:
    • linker (markup.DocstringLinker) - Used to look up URLs for classes.
    • context (APIDoc) - The context in which this node will be drawn; dotted names will be contextualized to this context.
    • collapsed (bool) - If true, then display this node as a simple box.
    • bgcolor (`str`) - The background color for this node.
    • options (dict) - A set of options used to control how the node should be displayed.
    • show_private_vars - If false, then private variables are filtered out of the attributes & operations lists. (Default: False)
    • show_magic_vars - If false, then magic variables (such as __init__ and __add__) are filtered out of the attributes & operations lists. (Default: True)
    • show_inherited_vars - If false, then inherited variables are filtered out of the attributes & operations lists. (Default: False)
    • max_attributes - The maximum number of attributes that should be listed in the attribute box. If the class has more than this number of attributes, some will be ellided. Ellipsis is marked with '...'.
    • max_operations - The maximum number of operations that should be listed in the operation box.
    • add_nodes_for_linked_attributes - If true, then link_attributes() will create new a collapsed node for the types of a linked attributes if no node yet exists for that type.
    Overrides: DotGraphNode.__init__

    link_attributes(self, nodes)

    source code 
    call graph 

    Convert any attributes with type descriptions corresponding to documented classes to edges. The following type descriptions are currently handled:

    • Dotted names: Create an attribute edge to the named type, labelled with the variable name.
    • Collections: Create an attribute edge to the named type, labelled with the variable name, and marked with '*' at the type end of the edge.
    • Mappings: Create an attribute edge to the named type, labelled with the variable name, connected to the class by a qualifier box that contains the key type description.
    • Optional: Create an attribute edge to the named type, labelled with the variable name, and marked with '0..1' at the type end of the edge.

    The edges created by link_attributes() are handled internally by DotGraphUmlClassNode; they should not be added directly to the DotGraph.

    Parameters:
    • nodes - A dictionary mapping from ClassDocs to DotGraphUmlClassNodes, used to look up the nodes for attribute types. If the add_nodes_for_linked_attributes option is used, then new nodes will be added to this dictionary for any types that are not already listed. These added nodes must be added to the DotGraph.

    _link_attribute(self, var, nodes)

    source code 
    call graph 
    Helper for link_attributes(): try to convert the attribute variable var into an edge, and add that edge to self.edges. Return True iff the variable was successfully converted to an edge (in which case, it should be removed from the attributes list).

    _add_attribute_edge(self, var, nodes, type_str, **attribs)

    source code 
    call graph 
    Helper for link_attributes(): try to add an edge for the given attribute variable var. Return True if successful.

    _operation_cell(self, var_doc)

    source code 
    call graph 
    To Do:
    • do 'word wrapping' on the signature, by starting a new row in the table, if necessary. How to indent the new line? Maybe use align=right? I don't think dot has a &nbsp;.
    • Optionally add return type info?

    _operation_arg(self, name, default, func_doc)

    source code 
    call graph 
    To Do:
    • Handle tuple args better
    • Optionally add type info?

    to_dotfile(self)

    source code 
    call graph 
    Return the dot commands that should be used to render this node.
    Overrides: DotGraphNode.to_dotfile
    (inherited documentation)

    Class Variable Details [hide private]

    COLLECTION_TYPE_RE

    A regular expression that matches descriptions of collection types.
    Value:
    re.compile(r'^(list|set|sequence|tuple|collection) of ([\w\.]+)$')
    

    MAPPING_TYPE_RE

    A regular expression that matches descriptions of mapping types.
    Value:
    re.compile(r'^(dict|dictionary|map|mapping) from ([\w\.]+) to ([\w\.]+\
    )$')
    

    MAPPING_TO_COLLECTION_TYPE_RE

    A regular expression that matches descriptions of mapping types whose value type is a collection.
    Value:
    re.compile(r'^(dict|dictionary|map|mapping) from ([\w\.]+) to (list|se\
    t|sequence|tuple|collection) of ([\w\.]+)$')
    

    OPTIONAL_TYPE_RE

    A regular expression that matches descriptions of optional types.
    Value:
    re.compile(r'^(None or|optional) ([\w\.]+)$|([\w\.]+) or None$')
    

    _ATTRIBUTE_CELL

    args: (url, tooltip, label)
    Value:
    '''
        <TR><TD ALIGN="LEFT" HREF="%s" TOOLTIP="%s">%s</TD></TR>
        '''
    

    _OPERATION_CELL

    args: (url, tooltip, label)
    Value:
    '''
        <TR><TD ALIGN="LEFT" HREF="%s" TOOLTIP="%s">%s</TD></TR>
        '''
    

    _QUALIFIER_CELL

    args: (port, bgcolor, label)
    Value:
    '''
        <TR><TD VALIGN="BOTTOM" PORT="%s" BGCOLOR="%s" BORDER="1">%s</TD><\
    /TR>
        '''
    

    _QUALIFIER_DIV

    Value:
    '''
        <TR><TD VALIGN="BOTTOM" HEIGHT="10" WIDTH="10" FIXEDSIZE="TRUE"></\
    TD></TR>
        '''
    

    _LABEL

    Args: (rowspan, bgcolor, classname, attributes, operations, qualifiers)
    Value:
    '''
        <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" CELLPADDING="0">
          <TR><TD ROWSPAN="%s">
            <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"
                   CELLPADDING="0" PORT="body" BGCOLOR="%s">
              <TR><TD>%s</TD></TR>
              <TR><TD><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0">
                %s</TABLE></TD></TR>
    ...
    

    _COLLAPSED_LABEL

    Value:
    '''
        <TABLE CELLBORDER="0" BGCOLOR="%s" PORT="body">
          <TR><TD>%s</TD></TR>
        </TABLE>'''
    

    Instance Variable Details [hide private]

    edges

    List of edges used to represent this node's attributes. These should not be added to the DotGraph; this node will generate their dotfile code directly.

    epydoc-3.0.1+dfsg/doc/api/epydoc-pysrc.html0000644000175000017500000011500410750103050021012 0ustar pronovicpronovic epydoc
    Package epydoc
    [hide private]
    [frames] | no frames]

    Source Code for Package epydoc

      1  # epydoc 
      2  # 
      3  # Copyright (C) 2005 Edward Loper 
      4  # Author: Edward Loper <edloper@loper.org> 
      5  # URL: <http://epydoc.sf.net> 
      6  # 
      7  # $Id: __init__.py 1691 2008-01-30 17:11:09Z edloper $ 
      8   
      9  """ 
     10  Automatic Python reference documentation generator.  Epydoc processes 
     11  Python modules and docstrings to generate formatted API documentation, 
     12  in the form of HTML pages.  Epydoc can be used via a command-line 
     13  interface (`epydoc.cli`) and a graphical interface (`epydoc.gui`). 
     14  Both interfaces let the user specify a set of modules or other objects 
     15  to document, and produce API documentation using the following steps: 
     16   
     17  1. Extract basic information about the specified objects, and objects 
     18     that are related to them (such as the values defined by a module). 
     19     This can be done via introspection, parsing, or both: 
     20   
     21     * *Introspection* imports the objects, and examines them directly 
     22       using Python's introspection mechanisms. 
     23     
     24     * *Parsing* reads the Python source files that define the objects, 
     25       and extracts information from those files. 
     26   
     27  2. Combine and process that information. 
     28   
     29     * **Merging**: Merge the information obtained from introspection & 
     30       parsing each object into a single structure. 
     31        
     32     * **Linking**: Replace any \"pointers\" that were created for 
     33       imported variables with the documentation that they point to. 
     34        
     35     * **Naming**: Assign unique *canonical names* to each of the 
     36       specified objects, and any related objects. 
     37        
     38     * **Docstrings**: Parse the docstrings of each of the specified 
     39       objects. 
     40        
     41     * **Inheritance**: Add variables to classes for any values that 
     42       they inherit from their base classes. 
     43   
     44  3. Generate output.  Output can be generated in a variety of formats: 
     45   
     46     * An HTML webpage. 
     47     
     48     * A LaTeX document (which can be rendered as a PDF file) 
     49   
     50     * A plaintext description. 
     51   
     52  .. digraph:: Overview of epydoc's architecture 
     53     :caption: The boxes represent steps in epydoc's processing chain. 
     54               Arrows are annotated with the data classes used to 
     55               communicate between steps.  The lines along the right 
     56               side mark what portions of the processing chain are 
     57               initiated by build_doc_index() and cli().  Click on 
     58               any item to see its documentation. 
     59                
     60     /* 
     61                    Python module or value                 *       * 
     62                        /           \                      |       | 
     63                       V             V                     |       | 
     64              introspect_docs()  parse_docs()              |       | 
     65                          \        /                       |       | 
     66                           V      V                        |       | 
     67                          merge_docs()                     |       | 
     68                               |              build_doc_index()  cli() 
     69                               V                           |       | 
     70                         link_imports()                    |       | 
     71                               |                           |       | 
     72                               V                           |       | 
     73                      assign_canonical_names()             |       | 
     74                               |                           |       | 
     75                               V                           |       | 
     76                        parse_docstrings()                 |       | 
     77                               |                           |       | 
     78                               V                           |       | 
     79                         inherit_docs()                    *       | 
     80                        /      |        \                          | 
     81                       V       V         V                         | 
     82                  HTMLWriter LaTeXWriter PlaintextWriter           * 
     83     */ 
     84   
     85     ranksep = 0.1; 
     86     node [shape="box", height="0", width="0"] 
     87      
     88     { /* Task nodes */ 
     89       node [fontcolor=\"#000060\"] 
     90       introspect  [label="Introspect value:\\nintrospect_docs()", 
     91                    href="<docintrospecter.introspect_docs>"] 
     92       parse       [label="Parse source code:\\nparse_docs()", 
     93                    href="<docparser.parse_docs>"] 
     94       merge       [label="Merge introspected & parsed docs:\\nmerge_docs()", 
     95                    href="<docbuilder.merge_docs>", width="2.5"] 
     96       link        [label="Link imports:\\nlink_imports()", 
     97                    href="<docbuilder.link_imports>", width="2.5"] 
     98       name        [label="Assign names:\\nassign_canonical_names()", 
     99                    href="<docbuilder.assign_canonical_names>", width="2.5"] 
    100       docstrings  [label="Parse docstrings:\\nparse_docstring()", 
    101                    href="<docstringparser.parse_docstring>", width="2.5"] 
    102       inheritance [label="Inherit docs from bases:\\ninherit_docs()", 
    103                    href="<docbuilder.inherit_docs>", width="2.5"] 
    104       write_html  [label="Write HTML output:\\nHTMLWriter", 
    105                   href="<docwriter.html>"] 
    106       write_latex  [label="Write LaTeX output:\\nLaTeXWriter", 
    107                   href="<docwriter.latex>"] 
    108       write_text  [label="Write text output:\\nPlaintextWriter", 
    109                   href="<docwriter.plaintext>"] 
    110     } 
    111   
    112     { /* Input & Output nodes */ 
    113       node [fontcolor=\"#602000\", shape="plaintext"] 
    114       input [label="Python module or value"] 
    115       output [label="DocIndex", href="<apidoc.DocIndex>"] 
    116     } 
    117   
    118     { /* Graph edges */ 
    119       edge [fontcolor=\"#602000\"] 
    120       input -> introspect 
    121       introspect -> merge [label="APIDoc", href="<apidoc.APIDoc>"] 
    122       input -> parse 
    123       parse -> merge [label="APIDoc", href="<apidoc.APIDoc>"] 
    124       merge -> link [label=" DocIndex", href="<apidoc.DocIndex>"] 
    125       link -> name [label=" DocIndex", href="<apidoc.DocIndex>"] 
    126       name -> docstrings [label=" DocIndex", href="<apidoc.DocIndex>"] 
    127       docstrings -> inheritance [label=" DocIndex", href="<apidoc.DocIndex>"] 
    128       inheritance -> output 
    129       output -> write_html 
    130       output -> write_latex 
    131       output -> write_text 
    132     } 
    133   
    134     { /* Task collections */ 
    135       node [shape="circle",label="",width=.1,height=.1] 
    136       edge [fontcolor="black", dir="none", fontcolor=\"#000060\"] 
    137       l3 -> l4 [label=" epydoc.\\l docbuilder.\\l build_doc_index()", 
    138                 href="<docbuilder.build_doc_index>"] 
    139       l1 -> l2 [label=" epydoc.\\l cli()", href="<cli>"] 
    140     } 
    141     { rank=same; l1 l3 input } 
    142     { rank=same; l2 write_html } 
    143     { rank=same; l4 output } 
    144   
    145  Package Organization 
    146  ==================== 
    147  The epydoc package contains the following subpackages and modules: 
    148   
    149  .. packagetree:: 
    150     :style: UML 
    151   
    152  The user interfaces are provided by the `gui` and `cli` modules. 
    153  The `apidoc` module defines the basic data types used to record 
    154  information about Python objects.  The programmatic interface to 
    155  epydoc is provided by `docbuilder`.  Docstring markup parsing is 
    156  handled by the `markup` package, and output generation is handled by 
    157  the `docwriter` package.  See the submodule list for more 
    158  information about the submodules and subpackages. 
    159   
    160  :group User Interface: gui, cli 
    161  :group Basic Data Types: apidoc 
    162  :group Documentation Generation: docbuilder, docintrospecter, docparser 
    163  :group Docstring Processing: docstringparser, markup 
    164  :group Output Generation: docwriter 
    165  :group Completeness Checking: checker 
    166  :group Miscellaneous: log, util, test, compat 
    167   
    168  :author: `Edward Loper <edloper@gradient.cis.upenn.edu>`__ 
    169  :requires: Python 2.3+ 
    170  :version: 3.0.1 
    171  :see: `The epydoc webpage <http://epydoc.sourceforge.net>`__ 
    172  :see: `The epytext markup language 
    173      manual <http://epydoc.sourceforge.net/epytext.html>`__ 
    174   
    175  :todo: Create a better default top_page than trees.html. 
    176  :todo: Fix trees.html to work when documenting non-top-level 
    177         modules/packages 
    178  :todo: Implement @include 
    179  :todo: Optimize epytext 
    180  :todo: More doctests 
    181  :todo: When introspecting, limit how much introspection you do (eg, 
    182         don't construct docs for imported modules' vars if it's 
    183         not necessary) 
    184   
    185  :bug: UserDict.* is interpreted as imported .. why?? 
    186   
    187  :license: IBM Open Source License 
    188  :copyright: |copy| 2006 Edward Loper 
    189   
    190  :newfield contributor: Contributor, Contributors (Alphabetical Order) 
    191  :contributor: `Glyph Lefkowitz  <mailto:glyph@twistedmatrix.com>`__ 
    192  :contributor: `Edward Loper  <mailto:edloper@gradient.cis.upenn.edu>`__ 
    193  :contributor: `Bruce Mitchener  <mailto:bruce@cubik.org>`__ 
    194  :contributor: `Jeff O'Halloran  <mailto:jeff@ohalloran.ca>`__ 
    195  :contributor: `Simon Pamies  <mailto:spamies@bipbap.de>`__ 
    196  :contributor: `Christian Reis  <mailto:kiko@async.com.br>`__ 
    197  :contributor: `Daniele Varrazzo  <mailto:daniele.varrazzo@gmail.com>`__ 
    198   
    199  .. |copy| unicode:: 0xA9 .. copyright sign 
    200  """ 
    201  __docformat__ = 'restructuredtext en' 
    202   
    203  __version__ = '3.0.1' 
    204  """The version of epydoc""" 
    205   
    206  __author__ = 'Edward Loper <edloper@gradient.cis.upenn.edu>' 
    207  """The primary author of eypdoc""" 
    208   
    209  __url__ = 'http://epydoc.sourceforge.net' 
    210  """The URL for epydoc's homepage""" 
    211   
    212  __license__ = 'IBM Open Source License' 
    213  """The license governing the use and distribution of epydoc""" 
    214   
    215  # [xx] this should probably be a private variable: 
    216  DEBUG = False 
    217  """True if debugging is turned on.""" 
    218   
    219  # Changes needed for docs: 
    220  #   - document the method for deciding what's public/private 
    221  #   - epytext: fields are defined slightly differently (@group) 
    222  #   - new fields 
    223  #   - document __extra_epydoc_fields__ and @newfield 
    224  #   - Add a faq? 
    225  #   - @type a,b,c: ... 
    226  #   - new command line option: --command-line-order 
    227   
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest-module.html0000644000175000017500000003665610750103050024120 0ustar pronovicpronovic epydoc.markup.doctest
    Package epydoc :: Package markup :: Module doctest
    [hide private]
    [frames] | no frames]

    Module doctest

    source code

    Syntax highlighting for doctest blocks. This module defines two functions, doctest_to_html() and doctest_to_latex(), which can be used to perform syntax highlighting on doctest blocks. It also defines the more general colorize_doctest(), which could be used to do syntac highlighting on doctest blocks with other output formats. (Both doctest_to_html() and doctest_to_latex() are defined using colorize_doctest().)

    Classes [hide private]
      DoctestColorizer
    An abstract base class for performing syntax highlighting on doctest blocks and other bits of Python code.
      XMLDoctestColorizer
    A subclass of DoctestColorizer that generates XML-like output.
      HTMLDoctestColorizer
    A subclass of DoctestColorizer that generates HTML output.
      LaTeXDoctestColorizer
    A subclass of DoctestColorizer that generates LaTeX output.
    Functions [hide private]
     
    doctest_to_html(s)
    Perform syntax highlighting on the given doctest string, and return the resulting HTML code.
    source code
    call graph 
     
    doctest_to_latex(s)
    Perform syntax highlighting on the given doctest string, and return the resulting LaTeX code.
    source code
    Function Details [hide private]

    doctest_to_html(s)

    source code 
    call graph 

    Perform syntax highlighting on the given doctest string, and return the resulting HTML code. This code consists of a <pre> block with class=py-doctest. Syntax highlighting is performed using the following css classes:

    • py-prompt -- the Python PS1 prompt (>>>)
    • py-more -- the Python PS2 prompt (...)
    • py-keyword -- a Python keyword (for, if, etc.)
    • py-builtin -- a Python builtin name (abs, dir, etc.)
    • py-string -- a string literal
    • py-comment -- a comment
    • py-except -- an exception traceback (up to the next >>>)
    • py-output -- the output from a doctest block.
    • py-defname -- the name of a function or class defined by a def or class statement.

    doctest_to_latex(s)

    source code 

    Perform syntax highlighting on the given doctest string, and return the resulting LaTeX code. This code consists of an alltt environment. Syntax highlighting is performed using the following new latex commands, which must be defined externally:

    • \pysrcprompt -- the Python PS1 prompt (>>>)
    • \pysrcmore -- the Python PS2 prompt (...)
    • \pysrckeyword -- a Python keyword (for, if, etc.)
    • \pysrcbuiltin -- a Python builtin name (abs, dir, etc.)
    • \pysrcstring -- a string literal
    • \pysrccomment -- a comment
    • \pysrcexcept -- an exception traceback (up to the next >>>)
    • \pysrcoutput -- the output from a doctest block.
    • \pysrcdefname -- the name of a function or class defined by a def or class statement.

    epydoc-3.0.1+dfsg/doc/api/epydoc.docbuilder-module.html0000644000175000017500000034724310750103050023266 0ustar pronovicpronovic epydoc.docbuilder
    Package epydoc :: Module docbuilder
    [hide private]
    [frames] | no frames]

    Module docbuilder

    source code

    Construct data structures that encode the API documentation for Python objects. These data structures are created using a series of steps:

    1. Building docs: Extract basic information about the objects, and objects that are related to them. This can be done by introspecting the objects' values (with epydoc.docintrospecter; or by parsing their source code (with epydoc.docparser.
    2. Merging: Combine the information obtained from introspection & parsing each object into a single structure.
    3. Linking: Replace any 'pointers' that were created for imported variables by their target (if it's available).
    4. Naming: Chose a unique 'canonical name' for each object.
    5. Docstring Parsing: Parse the docstring of each object, and extract any pertinant information.
    6. Inheritance: Add information about variables that classes inherit from their base classes.

    The documentation information for each individual object is represented using an APIDoc; and the documentation for a collection of objects is represented using a DocIndex.

    The main interface to epydoc.docbuilder consists of two functions:

    The remaining functions are used by these two main functions to perform individual steps in the creation of the documentation.

    Classes [hide private]
      BuildOptions
    Holds the parameters for a documentation building process.
      _ProgressEstimator
    Used to keep track of progress when generating the initial docs for the given items.
    Functions [hide private]
     
    _report_errors(name, introspect_doc, parse_doc, introspect_error, parse_error) source code
    call graph 
     
    find_overrides(class_doc)
    Set the overrides attribute for all variables in class_doc.
    source code
    call graph 
        Documentation Construction
    APIDoc
    build_doc(item, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None)
    Build API documentation for a given item, and return it as an APIDoc object.
    source code
    DocIndex
    build_doc_index(items, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None)
    Build API documentation for the given list of items, and return it in the form of a DocIndex.
    source code
    call graph 
     
    _report_valdoc_progress(i, val_doc, val_docs) source code
    call graph 
     
    _get_docs_from_items(items, options) source code
    call graph 
     
    _get_docs_from_pyobject(obj, options, progress_estimator) source code
     
    _get_docs_from_pyname(name, options, progress_estimator, suppress_warnings=False) source code
     
    _get_docs_from_pyscript(filename, options, progress_estimator) source code
     
    _get_docs_from_module_file(filename, options, progress_estimator, parent_docs=(None, None))
    Construct and return the API documentation for the python module with the given filename.
    source code
    call graph 
     
    _get_docs_from_submodules(item, pkg_docs, options, progress_estimator) source code
    call graph 
        Merging
     
    register_attribute_mergefunc(attrib, mergefunc)
    Register an attribute merge function.
    source code
     
    merge_docs(introspect_doc, parse_doc, cyclecheck=None, path=None)
    Merge the API documentation information that was obtained from introspection with information that was obtained from parsing.
    source code
    call graph 
     
    _merge_posargs_and_defaults(introspect_doc, parse_doc, path) source code
    call graph 
     
    merge_attribute(attrib, introspect_doc, parse_doc, cyclecheck, path) source code
    call graph 
     
    merge_variables(varlist1, varlist2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_value(value1, value2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_overrides(v1, v2, precedence, cyclecheck, path) source code
     
    merge_fget(v1, v2, precedence, cyclecheck, path) source code
     
    merge_fset(v1, v2, precedence, cyclecheck, path) source code
     
    merge_fdel(v1, v2, precedence, cyclecheck, path) source code
     
    merge_proxy_for(v1, v2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_bases(baselist1, baselist2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_posarg_defaults(defaults1, defaults2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_docstring(docstring1, docstring2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_docs_extracted_by(v1, v2, precedence, cyclecheck, path) source code
    call graph 
     
    merge_submodules(v1, v2, precedence, cyclecheck, path) source code
    call graph 
        Linking
     
    link_imports(val_doc, docindex) source code
    call graph 
        Naming
     
    assign_canonical_names(val_doc, name, docindex, score=0)
    Assign a canonical name to val_doc (if it doesn't have one already), and (recursively) to each variable in val_doc.
    source code
    call graph 
     
    _var_shadows_self(var_doc, varname) source code
    call graph 
     
    _fix_self_shadowing_var(var_doc, varname, docindex) source code
     
    _unreachable_name_for(val_doc, docindex) source code
    call graph 
        Inheritance
     
    inherit_docs(class_doc) source code
    call graph 
     
    _inherit_info(var_doc)
    Copy any relevant documentation information from the variable that var_doc overrides into var_doc itself.
    source code
    call graph 
    Variables [hide private]
      _INHERITED_ATTRIBS = ['descr', 'summary', 'metadata', 'extra_d...
        Merging
      MERGE_PRECEDENCE = {'canonical_name': 'introspect', 'docformat...
    Indicates whether information from introspection or parsing should be given precedence, for specific attributes.
      DEFAULT_MERGE_PRECEDENCE = 'introspect'
    Indicates whether information from introspection or parsing should be given precedence.
      _attribute_mergefunc_registry = {}
        Naming
      _name_scores = {<GenericValueDoc ??-12>: -10000, <ModuleDoc Co...
    A dictionary mapping from each ValueDoc to the score that has been assigned to its current cannonical name.
      _unreachable_names = {DottedName('??'): 14, DottedName('??', '...
    The set of names that have been used for unreachable objects.
    Function Details [hide private]

    build_doc(item, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None)

    source code 

    Build API documentation for a given item, and return it as an APIDoc object.

    Parameters:
    • item - The item to document, specified using any of the following:
      • A string, naming a python package directory (e.g., 'epydoc/markup')
      • A string, naming a python file (e.g., 'epydoc/docparser.py')
      • A string, naming a python object (e.g., 'epydoc.docparser.DocParser')
      • Any (non-string) python object (e.g., list.append)
    • introspect - If true, then use introspection to examine the specified items. Otherwise, just use parsing.
    • parse - If true, then use parsing to examine the specified items. Otherwise, just use introspection.
    Returns: APIDoc

    build_doc_index(items, introspect=True, parse=True, add_submodules=True, exclude_introspect=None, exclude_parse=None)

    source code 
    call graph 

    Build API documentation for the given list of items, and return it in the form of a DocIndex.

    Parameters:
    • items - The items to document, specified using any of the following:
      • A string, naming a python package directory (e.g., 'epydoc/markup')
      • A string, naming a python file (e.g., 'epydoc/docparser.py')
      • A string, naming a python object (e.g., 'epydoc.docparser.DocParser')
      • Any (non-string) python object (e.g., list.append)
    • introspect - If true, then use introspection to examine the specified items. Otherwise, just use parsing.
    • parse - If true, then use parsing to examine the specified items. Otherwise, just use introspection.
    Returns: DocIndex

    _get_docs_from_module_file(filename, options, progress_estimator, parent_docs=(None, None))

    source code 
    call graph 

    Construct and return the API documentation for the python module with the given filename.

    Parameters:
    • parent_docs - The ModuleDoc of the containing package. If parent_docs is not provided, then this method will check if the given filename is contained in a package; and if so, it will construct a stub ModuleDoc for the containing package(s). parent_docs is a tuple, where the first element is the parent from introspection, and the second element is the parent from parsing.

    register_attribute_mergefunc(attrib, mergefunc)

    source code 

    Register an attribute merge function. This function will be called by merge_docs() when it needs to merge the attribute values of two APIDocs.

    Parameters:
    • attrib - The name of the attribute whose values are merged by mergefunc.
    • mergefunc - The merge function, whose sinature is:
      >>> def mergefunc(introspect_val, parse_val, precedence, cyclecheck, path):
      ...     return calculate_merged_value(introspect_val, parse_val)

      Where introspect_val and parse_val are the two values to combine; precedence is a string indicating which value takes precedence for this attribute ('introspect' or 'parse'); cyclecheck is a value used by merge_docs() to make sure that it only visits each pair of docs once; and path is a string describing the path that was taken from the root to this attribute (used to generate log messages).

      If the merge function needs to call merge_docs, then it should pass cyclecheck and path back in. (When appropriate, a suffix should be added to path to describe the path taken to the merged values.)

    merge_docs(introspect_doc, parse_doc, cyclecheck=None, path=None)

    source code 
    call graph 

    Merge the API documentation information that was obtained from introspection with information that was obtained from parsing. introspect_doc and parse_doc should be two APIDoc instances that describe the same object. merge_docs combines the information from these two instances, and returns the merged APIDoc.

    If introspect_doc and parse_doc are compatible, then they will be merged -- i.e., they will be coerced to a common class, and their state will be stored in a shared dictionary. Once they have been merged, any change made to the attributes of one will affect the other. The value for the each of the merged APIDoc's attributes is formed by combining the values of the source APIDocs' attributes, as follows:

    • If either of the source attributes' value is UNKNOWN, then use the other source attribute's value.
    • Otherwise, if an attribute merge function has been registered for the attribute, then use that function to calculate the merged value from the two source attribute values.
    • Otherwise, if MERGE_PRECEDENCE is defined for the attribute, then use the attribute value from the source that it indicates.
    • Otherwise, use the attribute value from the source indicated by DEFAULT_MERGE_PRECEDENCE.

    If introspect_doc and parse_doc are not compatible (e.g., if their values have incompatible types), then merge_docs() will simply return either introspect_doc or parse_doc, depending on the value of DEFAULT_MERGE_PRECEDENCE. The two input APIDocs will not be merged or modified in any way.

    Parameters:
    • cyclecheck, path - These arguments should only be provided when merge_docs() is called by an attribute merge function. See register_attribute_mergefunc() for more details.

    assign_canonical_names(val_doc, name, docindex, score=0)

    source code 
    call graph 

    Assign a canonical name to val_doc (if it doesn't have one already), and (recursively) to each variable in val_doc. In particular, val_doc will be assigned the canonical name name iff either:

    • val_doc's canonical name is UNKNOWN; or
    • val_doc's current canonical name was assigned by this method; but the score of the new name (score) is higher than the score of the current name (score_dict[val_doc]).

    Note that canonical names will even be assigned to values like integers and None; but these should be harmless.

    find_overrides(class_doc)

    source code 
    call graph 

    Set the overrides attribute for all variables in class_doc. This needs to be done early (before docstring parsing), so we can know which docstrings to suppress warnings for.


    Variables Details [hide private]

    MERGE_PRECEDENCE

    Indicates whether information from introspection or parsing should be given precedence, for specific attributes. This dictionary maps from attribute names to either 'introspect' or 'parse'.

    Value:
    {'canonical_name': 'introspect',
     'docformat': 'parse',
     'docstring': 'introspect',
     'filename': 'parse',
     'is_alias': 'parse',
     'is_imported': 'introspect',
     'is_package': 'parse',
     'repr': 'parse',
    ...
    

    DEFAULT_MERGE_PRECEDENCE

    Indicates whether information from introspection or parsing should be given precedence. Should be either 'introspect' or 'parse'

    Value:
    'introspect'
    

    _name_scores

    A dictionary mapping from each ValueDoc to the score that has been assigned to its current cannonical name. If assign_canonical_names() finds a canonical name with a better score, then it will replace the old name.

    Value:
    {<GenericValueDoc ??-12>: -10000,
     <ModuleDoc ConfigParser>: 2147483647,
     <ValueDoc Tkinter.At>: 2147483647,
     <ValueDoc Tkinter.AtEnd>: 2147483647,
     <ValueDoc Tkinter.AtInsert>: 2147483647,
     <ValueDoc Tkinter.AtSelFirst>: 2147483647,
     <ValueDoc Tkinter.AtSelLast>: 2147483647,
     <ValueDoc Tkinter.BaseWidget>: 2147483647,
    ...
    

    _unreachable_names

    The set of names that have been used for unreachable objects. This is used to ensure there are no duplicate cannonical names assigned. _unreachable_names is a dictionary mapping from dotted names to integer ids, where the next unused unreachable name derived from dotted name n is DottedName('%s-%s' % (n, str(_unreachable_names[n]+1))

    Value:
    {DottedName('??'): 14,
     DottedName('??', 'APIDoc'): 4,
     DottedName('??', 'ApiLinkReader'): 2,
     DottedName('??', 'ArithmeticError'): 4,
     DottedName('??', 'AssertionError'): 1,
     DottedName('??', 'AttributeError'): 1,
     DottedName('??', 'Body'): 1,
     DottedName('??', 'ClassDoc'): 1,
    ...
    

    _INHERITED_ATTRIBS

    Value:
    ['descr',
     'summary',
     'metadata',
     'extra_docstring_fields',
     'type_descr',
     'arg_descrs',
     'arg_types',
     'return_descr',
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.compat-pysrc.html0000644000175000017500000014001410750103050022273 0ustar pronovicpronovic epydoc.compat
    Package epydoc :: Module compat
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.compat

      1  # epydoc -- Backwards compatibility 
      2  # 
      3  # Copyright (C) 2005 Edward Loper 
      4  # Author: Edward Loper <edloper@loper.org> 
      5  # URL: <http://epydoc.sf.net> 
      6  # 
      7  # $Id: util.py 956 2006-03-10 01:30:51Z edloper $ 
      8   
      9  """ 
     10  Backwards compatibility with previous versions of Python. 
     11   
     12  This module provides backwards compatibility by defining several 
     13  functions and classes that were not available in earlier versions of 
     14  Python.  Intented usage: 
     15   
     16      >>> from epydoc.compat import * 
     17   
     18  Currently, epydoc requires Python 2.3+. 
     19  """ 
     20  __docformat__ = 'epytext' 
     21   
     22  ###################################################################### 
     23  #{ New in Python 2.4 
     24  ###################################################################### 
     25   
     26  # set 
     27  try: 
     28      set 
     29  except NameError: 
     30      try: 
     31          from sets import Set as set, ImmutableSet as frozenset 
     32      except ImportError: 
     33          pass # use fallback, in the next section. 
     34   
     35  # sorted 
     36  try:  
     37      sorted 
     38  except NameError: 
    
    39 - def sorted(iterable, cmp=None, key=None, reverse=False):
    40 if key is None: 41 elts = list(iterable) 42 else: 43 elts = [(key(v), v) for v in iterable] 44 45 if reverse: elts.reverse() # stable sort. 46 if cmp is None: elts.sort() 47 else: elts.sort(cmp) 48 if reverse: elts.reverse() 49 50 if key is None: 51 return elts 52 else: 53 return [v for (k,v) in elts]
    54 55 # reversed 56 try: 57 reversed 58 except NameError:
    59 - def reversed(iterable):
    60 elts = list(iterable) 61 elts.reverse() 62 return elts
    63 64 ###################################################################### 65 #{ New in Python 2.3 66 ###################################################################### 67 # Below is my initial attempt at backporting enough code that 68 # epydoc 3 would run under python 2.2. However, I'm starting 69 # to think that it's not worth the trouble. At the very least, 70 # epydoc's current unicode handling still doesn't work under 71 # 2.2 (after the backports below), since the 'xmlcharrefreplace' 72 # error handler was introduced in python 2.3. 73 74 # # basestring 75 # try: 76 # basestring 77 # except NameError: 78 # basestring = (str, unicode) 79 80 # # sum 81 # try: 82 # sum 83 # except NameError: 84 # def _add(a,b): return a+b 85 # def sum(vals): return reduce(_add, vals, 0) 86 87 # # True & False 88 # try: 89 # True 90 # except NameError: 91 # True = 1 92 # False = 0 93 94 # # enumerate 95 # try: 96 # enumerate 97 # except NameError: 98 # def enumerate(iterable): 99 # lst = list(iterable) 100 # return zip(range(len(lst)), lst) 101 102 # # set 103 # try: 104 # set 105 # except NameError: 106 # class set(dict): 107 # def __init__(self, elts=()): 108 # dict.__init__(self, [(e,1) for e in elts]) 109 # def __repr__(self): 110 # return 'set(%r)' % list(self) 111 # def add(self, key): self[key] = 1 112 # def copy(self): 113 # return set(dict.copy(self)) 114 # def difference(self, other): 115 # return set([v for v in self if v not in other]) 116 # def difference_udpate(self, other): 117 # newval = self.difference(other) 118 # self.clear(); self.update(newval) 119 # def discard(self, elt): 120 # try: del self[elt] 121 # except: pass 122 # def intersection(self, other): 123 # return self.copy().update(other) 124 # def intersection_update(self, other): 125 # newval = self.intersection(other) 126 # self.clear(); self.update(newval) 127 # def issubset(self, other): 128 # for elt in self: 129 # if elt not in other: return False 130 # return True 131 # def issuperset(self, other): 132 # for elt in other: 133 # if elt not in self: return False 134 # return True 135 # def pop(self): self.popitem()[0] 136 # def remove(self, elt): del self[elt] 137 # def symmetric_difference(self, other): 138 # return set([v for v in list(self)+list(other) 139 # if (v in self)^(v in other)]) 140 # def symmatric_difference_update(self, other): 141 # newval = self.symmetric_difference(other) 142 # self.clear(); self.update(newval) 143 # def union(self, other): 144 # return set([v for v in list(self)+list(other) 145 # if (v in self) or (v in other)]) 146 # def union_update(self, other): 147 # newval = self.union(other) 148 # self.clear(); self.update(newval) 149 # def update(self, other): 150 # dict.update(self, set(other)) 151 152 # # optparse module 153 # try: 154 # import optparse 155 # except ImportError: 156 # import new, sys, getopt 157 # class _OptionVals: 158 # def __init__(self, vals): self.__dict__.update(vals) 159 # class OptionParser: 160 # def __init__(self, usage=None, version=None): 161 # self.usage = usage 162 # self.version = version 163 # self.shortops = ['h'] 164 # self.longops = [] 165 # self.option_specs = {} 166 # self.defaults = {} 167 # def fail(self, message, exitval=1): 168 # print >>sys.stderr, message 169 # system.exit(exitval) 170 # def add_option_group(self, group): pass 171 # def set_defaults(self, **defaults): 172 # self.defaults = defaults.copy() 173 # def parse_args(self): 174 # try: 175 # (opts, names) = getopt.getopt(sys.argv[1:], 176 # ''.join(self.shortops), 177 # self.longops) 178 # except getopt.GetoptError, e: 179 # self.fail(e) 180 181 # options = self.defaults.copy() 182 # for (opt,val) in opts: 183 # if opt == '-h': 184 # self.fail('No help available') 185 # if opt not in self.option_specs: 186 # self.fail('Unknown option %s' % opt) 187 # (action, dest, const) = self.option_specs[opt] 188 # if action == 'store': 189 # options[dest] = val 190 # elif action == 'store_const': 191 # options[dest] = const 192 # elif action == 'count': 193 # options[dest] = options.get(dest,0)+1 194 # elif action == 'append': 195 # options.setdefault(dest, []).append(val) 196 # else: 197 # self.fail('unsupported action: %s' % action) 198 # for (action,dest,const) in self.option_specs.values(): 199 # if dest not in options: 200 # if action == 'count': options[dest] = 0 201 # elif action == 'append': options[dest] = [] 202 # else: options[dest] = None 203 # for name in names: 204 # if name.startswith('-'): 205 # self.fail('names must follow options') 206 # return _OptionVals(options), names 207 # class OptionGroup: 208 # def __init__(self, optparser, name): 209 # self.optparser = optparser 210 # self.name = name 211 212 # def add_option(self, *args, **kwargs): 213 # action = 'store' 214 # dest = None 215 # const = None 216 # for (key,val) in kwargs.items(): 217 # if key == 'action': action = val 218 # elif key == 'dest': dest = val 219 # elif key == 'const': const = val 220 # elif key in ('help', 'metavar'): pass 221 # else: self.fail('unsupported: %s' % key) 222 223 # if action not in ('store_const', 'store_true', 'store_false', 224 # 'store', 'count', 'append'): 225 # self.fail('unsupported action: %s' % action) 226 227 # optparser = self.optparser 228 # for arg in args: 229 # if arg.startswith('--'): 230 # optparser.longops.append(arg[2:]) 231 # elif arg.startswith('-') and len(arg)==2: 232 # optparser.shortops += arg[1] 233 # if action in ('store', 'append'): 234 # optparser.shortops += ':' 235 # else: 236 # self.fail('bad option name %s' % arg) 237 # if action == 'store_true': 238 # (action, const) = ('store_const', True) 239 # if action == 'store_false': 240 # (action, const) = ('store_const', False) 241 # optparser.option_specs[arg] = (action, dest, const) 242 243 # # Install a fake module. 244 # optparse = new.module('optparse') 245 # optparse.OptionParser = OptionParser 246 # optparse.OptionGroup = OptionGroup 247 # sys.modules['optparse'] = optparse 248 # # Clean up 249 # del OptionParser, OptionGroup 250

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext-module.html0000644000175000017500000017047310750103050026107 0ustar pronovicpronovic epydoc.markup.restructuredtext
    Package epydoc :: Package markup :: Module restructuredtext
    [hide private]
    [frames] | no frames]

    Module restructuredtext

    source code

    Epydoc parser for ReStructuredText strings. ReStructuredText is the standard markup language used by the Docutils project. parse_docstring() provides the primary interface to this module; it returns a ParsedRstDocstring, which supports all of the methods defined by ParsedDocstring.

    ParsedRstDocstring is basically just a ParsedDocstring wrapper for the docutils.nodes.document class.

    Creating ParsedRstDocstrings

    ParsedRstDocstrings are created by the parse_document function, using the docutils.core.publish_string() method, with the following helpers:

    • An _EpydocReader is used to capture all error messages as it parses the docstring.
    • A _DocumentPseudoWriter is used to extract the document itself, without actually writing any output. The document is saved for further processing. The settings for the writer are copied from docutils.writers.html4css1.Writer, since those settings will be used when we actually write the docstring to html.

    Using ParsedRstDocstrings

    ParsedRstDocstrings support all of the methods defined by ParsedDocstring; but only the following four methods have non-default behavior:


    To Do: Add ParsedRstDocstring.to_latex()

    Classes [hide private]
      OptimizedReporter
    A reporter that ignores all debug messages.
      ParsedRstDocstring
    An encoded version of a ReStructuredText docstring.
      _EpydocReader
    A reader that captures all errors that are generated by parsing, and appends them to a list.
      _DocumentPseudoWriter
    A pseudo-writer for the docutils framework, that can be used to access the document itself.
      _SummaryExtractor
    A docutils node visitor that extracts the first sentence from the first paragraph in a document.
      _TermsExtractor
    A docutils node visitor that extracts the terms from documentation.
      _SplitFieldsTranslator
    A docutils translator that removes all fields from a document, and collects them into the instance variable fields
      _EpydocLaTeXTranslator
      _EpydocHTMLTranslator
        Graph Generation Directives
      dotgraph
    A custom docutils node that should be rendered using Graphviz dot.
    Functions [hide private]
    ParsedDocstring
    parse_docstring(docstring, errors, **options)
    Parse the given docstring, which is formatted using ReStructuredText; and return a ParsedDocstring representation of its contents.
    source code
    call graph 
     
    latex_head_prefix() source code
     
    python_code_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
    A custom restructuredtext directive which can be used to display syntax-highlighted Python code blocks.
    source code
     
    term_role(name, rawtext, text, lineno, inliner, options={}, content=[]) source code
        Graph Generation Directives
     
    _dir_option(argument)
    A directive option spec for the orientation of a graph.
    source code
     
    digraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
    A custom restructuredtext directive which can be used to display Graphviz dot graphs.
    source code
    call graph 
     
    _construct_digraph(docindex, context, linker, title, caption, body)
    Graph generator for digraph_directive
    source code
    call graph 
     
    classtree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
    A custom restructuredtext directive which can be used to graphically display a class hierarchy.
    source code
    call graph 
     
    _construct_classtree(docindex, context, linker, arguments, options)
    Graph generator for classtree_directive
    source code
    call graph 
     
    packagetree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
    A custom restructuredtext directive which can be used to graphically display a package hierarchy.
    source code
    call graph 
     
    _construct_packagetree(docindex, context, linker, arguments, options)
    Graph generator for packagetree_directive
    source code
    call graph 
     
    importgraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine) source code
    call graph 
     
    _construct_importgraph(docindex, context, linker, arguments, options)
    Graph generator for importgraph_directive
    source code
    call graph 
     
    callgraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine) source code
     
    _construct_callgraph(docindex, context, linker, arguments, options)
    Graph generator for callgraph_directive
    source code
    Variables [hide private]
      CONSOLIDATED_FIELDS = {'arguments': 'arg', 'cvariables': 'cvar...
    A dictionary encoding the set of 'consolidated fields' that can be used.
      CONSOLIDATED_DEFLIST_FIELDS = ['param', 'arg', 'var', 'ivar', ...
    A list of consolidated fields whose bodies may be specified using a definition list, rather than a bulleted list.
    Function Details [hide private]

    parse_docstring(docstring, errors, **options)

    source code 
    call graph 

    Parse the given docstring, which is formatted using ReStructuredText; and return a ParsedDocstring representation of its contents.

    Parameters:
    • docstring (string) - The docstring to parse
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored.
    • options - Extra options. Unknown options are ignored. Currently, no extra options are defined.
    Returns: ParsedDocstring

    python_code_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)

    source code 

    A custom restructuredtext directive which can be used to display syntax-highlighted Python code blocks. This directive takes no arguments, and the body should contain only Python code. This directive can be used instead of doctest blocks when it is inconvenient to list prompts on each line, or when you would prefer that the output not contain prompts (e.g., to make copy/paste easier).

    digraph_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)

    source code 
    call graph 

    A custom restructuredtext directive which can be used to display Graphviz dot graphs. This directive takes a single argument, which is used as the graph's name. The contents of the directive are used as the body of the graph. Any href attributes whose value has the form <name> will be replaced by the URL of the object with that name. Here's a simple example:

    .. digraph:: example_digraph
      a -> b -> c
      c -> a [dir="none"]
    

    classtree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)

    source code 
    call graph 

    A custom restructuredtext directive which can be used to graphically display a class hierarchy. If one or more arguments are given, then those classes and all their descendants will be displayed. If no arguments are given, and the directive is in a class's docstring, then that class and all its descendants will be displayed. It is an error to use this directive with no arguments in a non-class docstring.

    Options:

    • :dir: -- Specifies the orientation of the graph. One of down, right (default), left, up.

    packagetree_directive(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)

    source code 
    call graph 

    A custom restructuredtext directive which can be used to graphically display a package hierarchy. If one or more arguments are given, then those packages and all their submodules will be displayed. If no arguments are given, and the directive is in a package's docstring, then that package and all its submodules will be displayed. It is an error to use this directive with no arguments in a non-package docstring.

    Options:

    • :dir: -- Specifies the orientation of the graph. One of down, right (default), left, up.

    Variables Details [hide private]

    CONSOLIDATED_FIELDS

    A dictionary whose keys are the "consolidated fields" that are recognized by epydoc; and whose values are the corresponding epydoc field names that should be used for the individual fields.

    Value:
    {'arguments': 'arg',
     'cvariables': 'cvar',
     'exceptions': 'except',
     'groups': 'group',
     'ivariables': 'ivar',
     'keywords': 'keyword',
     'parameters': 'param',
     'types': 'type',
    ...
    

    CONSOLIDATED_DEFLIST_FIELDS

    A list of consolidated fields whose bodies may be specified using a definition list, rather than a bulleted list. For these fields, the 'classifier' for each term in the definition list is translated into a @type field.

    Value:
    ['param', 'arg', 'var', 'ivar', 'cvar', 'keyword']
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.DottedName.InvalidDottedName-class.html0000644000175000017500000001520610750103050027575 0ustar pronovicpronovic epydoc.apidoc.DottedName.InvalidDottedName
    Package epydoc :: Module apidoc :: Class DottedName :: Class InvalidDottedName
    [hide private]
    [frames] | no frames]

    Class InvalidDottedName

    source code


    An exception raised by the DottedName constructor when one of its arguments is not a valid dotted name.

    Instance Methods [hide private]

    Inherited from exceptions.Exception: __getitem__, __init__, __str__

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.checker-module.html0000644000175000017500000000314710750103050023331 0ustar pronovicpronovic checker

    Module checker


    Classes

    DocChecker

    Variables


    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.util-pysrc.html0000644000175000017500000026460610750103050022003 0ustar pronovicpronovic epydoc.util
    Package epydoc :: Module util
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.util

      1  # epydoc -- Utility functions 
      2  # 
      3  # Copyright (C) 2005 Edward Loper 
      4  # Author: Edward Loper <edloper@loper.org> 
      5  # URL: <http://epydoc.sf.net> 
      6  # 
      7  # $Id: util.py 1671 2008-01-29 02:55:49Z edloper $ 
      8   
      9  """ 
     10  Miscellaneous utility functions that are used by multiple modules. 
     11   
     12  @group Python source types: is_module_file, is_package_dir, is_pyname, 
     13      py_src_filename 
     14  @group Text processing: wordwrap, decode_with_backslashreplace, 
     15      plaintext_to_html 
     16  """ 
     17  __docformat__ = 'epytext en' 
     18   
     19  import os, os.path, re 
     20   
     21  ###################################################################### 
     22  ## Python Source Types 
     23  ###################################################################### 
     24   
     25  PY_SRC_EXTENSIONS = ['.py', '.pyw'] 
     26  PY_BIN_EXTENSIONS = ['.pyc', '.so', '.pyd'] 
     27   
    
    28 -def is_module_file(path):
    29 # Make sure it's a file name. 30 if not isinstance(path, basestring): 31 return False 32 (dir, filename) = os.path.split(path) 33 (basename, extension) = os.path.splitext(filename) 34 return (os.path.isfile(path) and 35 re.match('[a-zA-Z_]\w*$', basename) and 36 extension in PY_SRC_EXTENSIONS+PY_BIN_EXTENSIONS)
    37
    38 -def is_src_filename(filename):
    39 if not isinstance(filename, basestring): return False 40 if not os.path.exists(filename): return False 41 return os.path.splitext(filename)[1] in PY_SRC_EXTENSIONS
    42
    43 -def is_package_dir(dirname):
    44 """ 45 Return true if the given directory is a valid package directory 46 (i.e., it names a directory that contains a valid __init__ file, 47 and its name is a valid identifier). 48 """ 49 # Make sure it's a directory name. 50 if not isinstance(dirname, basestring): 51 return False 52 if not os.path.isdir(dirname): 53 return False 54 dirname = os.path.abspath(dirname) 55 # Make sure it's a valid identifier. (Special case for 56 # "foo/", where os.path.split -> ("foo", "").) 57 (parent, dir) = os.path.split(dirname) 58 if dir == '': (parent, dir) = os.path.split(parent) 59 60 # The following constraint was removed because of sourceforge 61 # bug #1787028 -- in some cases (eg eggs), it's too strict. 62 #if not re.match('\w+$', dir): 63 # return False 64 65 for name in os.listdir(dirname): 66 filename = os.path.join(dirname, name) 67 if name.startswith('__init__.') and is_module_file(filename): 68 return True 69 else: 70 return False
    71
    72 -def is_pyname(name):
    73 return re.match(r"\w+(\.\w+)*$", name)
    74
    75 -def py_src_filename(filename):
    76 basefile, extension = os.path.splitext(filename) 77 if extension in PY_SRC_EXTENSIONS: 78 return filename 79 else: 80 for ext in PY_SRC_EXTENSIONS: 81 if os.path.isfile('%s%s' % (basefile, ext)): 82 return '%s%s' % (basefile, ext) 83 else: 84 raise ValueError('Could not find a corresponding ' 85 'Python source file for %r.' % filename)
    86
    87 -def munge_script_name(filename):
    88 name = os.path.split(filename)[1] 89 name = re.sub(r'\W', '_', name) 90 return 'script-'+name
    91 92 ###################################################################### 93 ## Text Processing 94 ###################################################################### 95
    97 r""" 98 Convert the given 8-bit string into unicode, treating any 99 character c such that ord(c)<128 as an ascii character, and 100 converting any c such that ord(c)>128 into a backslashed escape 101 sequence. 102 103 >>> decode_with_backslashreplace('abc\xff\xe8') 104 u'abc\\xff\\xe8' 105 """ 106 # s.encode('string-escape') is not appropriate here, since it 107 # also adds backslashes to some ascii chars (eg \ and '). 108 assert isinstance(s, str) 109 return (s 110 .decode('latin1') 111 .encode('ascii', 'backslashreplace') 112 .decode('ascii'))
    113
    114 -def wordwrap(str, indent=0, right=75, startindex=0, splitchars=''):
    115 """ 116 Word-wrap the given string. I.e., add newlines to the string such 117 that any lines that are longer than C{right} are broken into 118 shorter lines (at the first whitespace sequence that occurs before 119 index C{right}). If the given string contains newlines, they will 120 I{not} be removed. Any lines that begin with whitespace will not 121 be wordwrapped. 122 123 @param indent: If specified, then indent each line by this number 124 of spaces. 125 @type indent: C{int} 126 @param right: The right margin for word wrapping. Lines that are 127 longer than C{right} will be broken at the first whitespace 128 sequence before the right margin. 129 @type right: C{int} 130 @param startindex: If specified, then assume that the first line 131 is already preceeded by C{startindex} characters. 132 @type startindex: C{int} 133 @param splitchars: A list of non-whitespace characters which can 134 be used to split a line. (E.g., use '/\\' to allow path names 135 to be split over multiple lines.) 136 @rtype: C{str} 137 """ 138 if splitchars: 139 chunks = re.split(r'( +|\n|[^ \n%s]*[%s])' % 140 (re.escape(splitchars), re.escape(splitchars)), 141 str.expandtabs()) 142 else: 143 chunks = re.split(r'( +|\n)', str.expandtabs()) 144 result = [' '*(indent-startindex)] 145 charindex = max(indent, startindex) 146 for chunknum, chunk in enumerate(chunks): 147 if (charindex+len(chunk) > right and charindex > 0) or chunk == '\n': 148 result.append('\n' + ' '*indent) 149 charindex = indent 150 if chunk[:1] not in ('\n', ' '): 151 result.append(chunk) 152 charindex += len(chunk) 153 else: 154 result.append(chunk) 155 charindex += len(chunk) 156 return ''.join(result).rstrip()+'\n'
    157
    158 -def plaintext_to_html(s):
    159 """ 160 @return: An HTML string that encodes the given plaintext string. 161 In particular, special characters (such as C{'<'} and C{'&'}) 162 are escaped. 163 @rtype: C{string} 164 """ 165 s = s.replace('&', '&amp;').replace('"', '&quot;') 166 s = s.replace('<', '&lt;').replace('>', '&gt;') 167 return s
    168
    169 -def plaintext_to_latex(str, nbsp=0, breakany=0):
    170 """ 171 @return: A LaTeX string that encodes the given plaintext string. 172 In particular, special characters (such as C{'$'} and C{'_'}) 173 are escaped, and tabs are expanded. 174 @rtype: C{string} 175 @param breakany: Insert hyphenation marks, so that LaTeX can 176 break the resulting string at any point. This is useful for 177 small boxes (e.g., the type box in the variable list table). 178 @param nbsp: Replace every space with a non-breaking space 179 (C{'~'}). 180 """ 181 # These get converted to hyphenation points later 182 if breakany: str = re.sub('(.)', '\\1\1', str) 183 184 # These get converted to \textbackslash later. 185 str = str.replace('\\', '\0') 186 187 # Expand tabs 188 str = str.expandtabs() 189 190 # These elements need to be backslashed. 191 str = re.sub(r'([#$&%_\${}])', r'\\\1', str) 192 193 # These elements have special names. 194 str = str.replace('|', '{\\textbar}') 195 str = str.replace('<', '{\\textless}') 196 str = str.replace('>', '{\\textgreater}') 197 str = str.replace('^', '{\\textasciicircum}') 198 str = str.replace('~', '{\\textasciitilde}') 199 str = str.replace('\0', r'{\textbackslash}') 200 201 # replace spaces with non-breaking spaces 202 if nbsp: str = str.replace(' ', '~') 203 204 # Convert \1's to hyphenation points. 205 if breakany: str = str.replace('\1', r'\-') 206 207 return str
    208
    209 -class RunSubprocessError(OSError):
    210 - def __init__(self, cmd, out, err):
    211 OSError.__init__(self, '%s failed' % cmd[0]) 212 self.out = out 213 self.err = err
    214
    215 -def run_subprocess(cmd, data=None):
    216 """ 217 Execute the command C{cmd} in a subprocess. 218 219 @param cmd: The command to execute, specified as a list 220 of string. 221 @param data: A string containing data to send to the 222 subprocess. 223 @return: A tuple C{(out, err)}. 224 @raise OSError: If there is any problem executing the 225 command, or if its exitval is not 0. 226 """ 227 if isinstance(cmd, basestring): 228 cmd = cmd.split() 229 230 # Under Python 2.4+, use subprocess 231 try: 232 from subprocess import Popen, PIPE 233 pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) 234 out, err = pipe.communicate(data) 235 if hasattr(pipe, 'returncode'): 236 if pipe.returncode == 0: 237 return out, err 238 else: 239 raise RunSubprocessError(cmd, out, err) 240 else: 241 # Assume that there was an error iff anything was written 242 # to the child's stderr. 243 if err == '': 244 return out, err 245 else: 246 raise RunSubprocessError(cmd, out, err) 247 except ImportError: 248 pass 249 250 # Under Python 2.3 or earlier, on unix, use popen2.Popen3 so we 251 # can access the return value. 252 import popen2 253 if hasattr(popen2, 'Popen3'): 254 pipe = popen2.Popen3(' '.join(cmd), True) 255 to_child = pipe.tochild 256 from_child = pipe.fromchild 257 child_err = pipe.childerr 258 if data: 259 to_child.write(data) 260 to_child.close() 261 out = err = '' 262 while pipe.poll() is None: 263 out += from_child.read() 264 err += child_err.read() 265 out += from_child.read() 266 err += child_err.read() 267 if pipe.wait() == 0: 268 return out, err 269 else: 270 raise RunSubprocessError(cmd, out, err) 271 272 # Under Python 2.3 or earlier, on non-unix, use os.popen3 273 else: 274 to_child, from_child, child_err = os.popen3(' '.join(cmd), 'b') 275 if data: 276 try: 277 to_child.write(data) 278 # Guard for a broken pipe error 279 except IOError, e: 280 raise OSError(e) 281 to_child.close() 282 out = from_child.read() 283 err = child_err.read() 284 # Assume that there was an error iff anything was written 285 # to the child's stderr. 286 if err == '': 287 return out, err 288 else: 289 raise RunSubprocessError(cmd, out, err)
    290

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter-module.html0000644000175000017500000001547010750103050023146 0ustar pronovicpronovic epydoc.docwriter
    Package epydoc :: Package docwriter
    [hide private]
    [frames] | no frames]

    Package docwriter

    source code

    Output generation.

    Submodules [hide private]

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.pyval_repr.PyvalColorizer-class.html0000644000175000017500000014275310750103050027435 0ustar pronovicpronovic epydoc.markup.pyval_repr.PyvalColorizer
    Package epydoc :: Package markup :: Module pyval_repr :: Class PyvalColorizer
    [hide private]
    [frames] | no frames]

    Class PyvalColorizer

    source code

    Syntax highlighter for Python values.

    Instance Methods [hide private]
     
    __init__(self, linelen=75, maxlines=5, linebreakok=True, sort=True) source code
    call graph 
     
    colorize(self, pyval, parse_repr=None, min_score=None)
    Returns: A ColorizedPyvalRepr describing the given pyval.
    source code
    call graph 
     
    _colorize(self, pyval, state) source code
    call graph 
     
    _sort(self, items) source code
    call graph 
     
    _trim_result(self, result, num_chars) source code
    call graph 
     
    _multiline(self, func, pyval, state, *args)
    Helper for container-type colorizers.
    source code
    call graph 
     
    _colorize_iter(self, pyval, state, prefix, suffix) source code
    call graph 
     
    _colorize_dict(self, items, state, prefix, suffix) source code
    call graph 
     
    _colorize_str(self, pyval, state, prefix, encoding) source code
    call graph 
     
    _colorize_re(self, pyval, state) source code
    call graph 
     
    _colorize_re_flags(self, flags, state) source code
    call graph 
     
    _colorize_re_tree(self, tree, state, noparen, groups) source code
    call graph 
     
    _output(self, s, tag, state)
    Add the string `s` to the result list, tagging its contents with tag `tag`.
    source code
    call graph 
    Class Variables [hide private]
      GROUP_TAG = 'variable-group'
      COMMA_TAG = 'variable-op'
      COLON_TAG = 'variable-op'
      CONST_TAG = None
      NUMBER_TAG = None
      QUOTE_TAG = 'variable-quote'
      STRING_TAG = 'variable-string'
      RE_CHAR_TAG = None
      RE_GROUP_TAG = 're-group'
      RE_REF_TAG = 're-ref'
      RE_OP_TAG = 're-op'
      RE_FLAGS_TAG = 're-flags'
      ELLIPSIS = Element(code, u'...', style='variable-ellipsis')
      LINEWRAP = Element(symbol, u'crarr')
      UNKNOWN_REPR = Element(code, u'??', style='variable-unknown')
      GENERIC_OBJECT_RE = re.compile(r'(?i)^<.* at 0x[0-9a-f]+>$')
      ESCAPE_UNICODE = False
    Method Details [hide private]

    colorize(self, pyval, parse_repr=None, min_score=None)

    source code 
    call graph 
    Returns:
    A ColorizedPyvalRepr describing the given pyval.

    _multiline(self, func, pyval, state, *args)

    source code 
    call graph 

    Helper for container-type colorizers. First, try calling func(pyval, state, *args) with linebreakok set to false; and if that fails, then try again with it set to true.

    _output(self, s, tag, state)

    source code 
    call graph 

    Add the string `s` to the result list, tagging its contents with tag `tag`. Any lines that go beyond `self.linelen` will be line-wrapped. If the total number of lines exceeds `self.maxlines`, then raise a `_Maxlines` exception.


    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest.DoctestColorizer-class.html0000644000175000017500000015055610750103050027231 0ustar pronovicpronovic epydoc.markup.doctest.DoctestColorizer
    Package epydoc :: Package markup :: Module doctest :: Class DoctestColorizer
    [hide private]
    [frames] | no frames]

    Class DoctestColorizer

    source code


    An abstract base class for performing syntax highlighting on doctest blocks and other bits of Python code. Subclasses should provide definitions for:

    Instance Methods [hide private]
     
    colorize_inline(self, s)
    Colorize a string containing Python code.
    source code
     
    colorize_codeblock(self, s)
    Colorize a string containing only Python code.
    source code
     
    colorize_doctest(self, s, strip_directives=False)
    Colorize a string containing one or more doctest examples.
    source code
    call graph 
     
    subfunc(self, match) source code
    call graph 
     
    markup(self, s, tag)
    Apply syntax highlighting to a single substring from a doctest block.
    source code
    Class Variables [hide private]
      PREFIX = None
    A string that is added to the beginning of the strings returned by colorize_codeblock and colorize_doctest.
      SUFFIX = None
    A string that is added to the end of the strings returned by colorize_codeblock and colorize_doctest.
      _KEYWORDS = ['and', 'del', 'for', 'is', 'raiseassert', 'elif',...
    A list of the names of all Python keywords.
      _BUILTINS = ['clear', 'copy', 'fromkeys', 'get', 'has_key', 'i...
    A list of all Python builtins.
      _KEYWORD_GRP = '\\band\\b|\\bdel\\b|\\bfor\\b|\\bis\\b|\\brais...
    A regexp group that matches keywords.
      _BUILTIN_GRP = '(?<!\\.)(?:\\bclear\\b|\\bcopy\\b|\\bfromkeys\...
    A regexp group that matches Python builtins.
      _STRING_GRP = '("""("""|.*?((?!").)"""))|("("|.*?((?!").)"))|(...
    A regexp group that matches Python strings.
      _COMMENT_GRP = '(#.*?$)'
    A regexp group that matches Python comments.
      _PROMPT1_GRP = '^[ \\t]*>>>(?:[ \\t]|$)'
    A regexp group that matches Python ">>>" prompts.
      _PROMPT2_GRP = '^[ \\t]*\\.\\.\\.(?:[ \\t]|$)'
    A regexp group that matches Python "..." prompts.
      _DEFINE_GRP = '\\b(?:def|class)[ \\t]+\\w+'
    A regexp group that matches function and class definitions.
      PROMPT_RE = re.compile(r'(?ms)(^[ \t]*>>>(?:[ \t]|$)|[ \t]*\.\...
    A regexp that matches Python prompts
      PROMPT2_RE = re.compile(r'(?ms)(^[ \t]*\.\.\.(?:[ \t]|$))')
    A regexp that matches Python "..." prompts.
      EXCEPT_RE = re.compile(r'(?ms)^[ \t]*Traceback \(most recent c...
    A regexp that matches doctest exception blocks.
      DOCTEST_DIRECTIVE_RE = re.compile(r'#[ \t]*doctest:.*')
    A regexp that matches doctest directives.
      DOCTEST_RE = re.compile(r'(?ms)(.*?)((?P<STRING>("""("""|.*?((...
    A regexp that matches all of the regions of a doctest block that should be colored.
      DOCTEST_EXAMPLE_RE = re.compile(r'(?mx)(?P<source>(?:^(?P<inde...
    This regular expression is used to find doctest examples in a string.
      _BI = 'values'
      _KW = 'as'
    Method Details [hide private]

    colorize_inline(self, s)

    source code 

    Colorize a string containing Python code. Do not add the PREFIX and SUFFIX strings to the returned value. This method is intended for generating syntax-highlighted strings that are appropriate for inclusion as inline expressions.

    colorize_codeblock(self, s)

    source code 

    Colorize a string containing only Python code. This method differs from colorize_doctest in that it will not search for doctest prompts when deciding how to colorize the string.

    markup(self, s, tag)

    source code 

    Apply syntax highlighting to a single substring from a doctest block. s is the substring, and tag is the tag that should be applied to the substring. tag will be one of the following strings:

    • prompt -- the Python PS1 prompt (>>>)
    • more -- the Python PS2 prompt (...)
    • keyword -- a Python keyword (for, if, etc.)
    • builtin -- a Python builtin name (abs, dir, etc.)
    • string -- a string literal
    • comment -- a comment
    • except -- an exception traceback (up to the next >>>)
    • output -- the output from a doctest block.
    • defname -- the name of a function or class defined by a def or class statement.
    • other -- anything else (does *not* include output.)

    Class Variable Details [hide private]

    PREFIX

    A string that is added to the beginning of the strings returned by colorize_codeblock and colorize_doctest. Typically, this string begins a preformatted area.

    Value:
    None
    

    SUFFIX

    A string that is added to the end of the strings returned by colorize_codeblock and colorize_doctest. Typically, this string ends a preformatted area.

    Value:
    None
    

    _KEYWORDS

    A list of the names of all Python keywords. ('as' is included even though it is technically not a keyword.)

    Value:
    ['and',
     'del',
     'for',
     'is',
     'raiseassert',
     'elif',
     'from',
     'lambda',
    ...
    

    _BUILTINS

    A list of all Python builtins.

    Value:
    ['clear',
     'copy',
     'fromkeys',
     'get',
     'has_key',
     'items',
     'iteritems',
     'iterkeys',
    ...
    

    _KEYWORD_GRP

    A regexp group that matches keywords.

    Value:
    '\\band\\b|\\bdel\\b|\\bfor\\b|\\bis\\b|\\braiseassert\\b|\\belif\\b|\\
    \bfrom\\b|\\blambda\\b|\\breturnbreak\\b|\\belse\\b|\\bglobal\\b|\\bno\
    t\\b|\\btryclass\\b|\\bexcept\\b|\\bif\\b|\\bor\\b|\\bwhilecontinue\\b\
    |\\bexec\\b|\\bimport\\b|\\bpass\\b|\\byielddef\\b|\\bfinally\\b|\\bin\
    \\b|\\bprint\\b|\\bas\\b'
    

    _BUILTIN_GRP

    A regexp group that matches Python builtins.

    Value:
    '(?<!\\.)(?:\\bclear\\b|\\bcopy\\b|\\bfromkeys\\b|\\bget\\b|\\bhas_key\
    \\b|\\bitems\\b|\\biteritems\\b|\\biterkeys\\b|\\bitervalues\\b|\\bkey\
    s\\b|\\bpop\\b|\\bpopitem\\b|\\bsetdefault\\b|\\bupdate\\b|\\bvalues\\\
    b)'
    

    _STRING_GRP

    A regexp group that matches Python strings.

    Value:
    '("""("""|.*?((?!").)"""))|("("|.*?((?!").)"))|(\'\'\'(\'\'\'|.*?[^\\\\
    \\']\'\'\'))|(\'(\'|.*?[^\\\\\']\'))'
    

    PROMPT_RE

    A regexp that matches Python prompts

    Value:
    re.compile(r'(?ms)(^[ \t]*>>>(?:[ \t]|$)|[ \t]*\.\.\.(?:[ \t]|$))')
    

    EXCEPT_RE

    A regexp that matches doctest exception blocks.

    Value:
    re.compile(r'(?ms)^[ \t]*Traceback \(most recent call last\):.*')
    

    DOCTEST_RE

    A regexp that matches all of the regions of a doctest block that should be colored.

    Value:
    re.compile(r'(?ms)(.*?)((?P<STRING>("""("""|.*?((?!").)"""))|("("|.*?(\
    (?!").)"))|(\'\'\'(\'\'\'|.*?[^\\\']\'\'\'))|(\'(\'|.*?[^\\\']\')))|(?\
    P<COMMENT>(#.*?$))|(?P<DEFINE>\b(?:def|class)[ \t]+\w+)|(?P<KEYWORD>\b\
    and\b|del\b|for\b|is\b|raiseassert\b|elif\b|from\b|lambda\b|returnbrea\
    k\b|else\b|global\b|not\b|tryclass\b|except\b|if\b|or\b|whilecontinue\\
    b|exec\b|import\b|pass\b|yielddef\b|finally\b|in\b|print\b|as\b)|(?P<B\
    UILTIN>(?<!\.)(?:\bclear\b|copy\b|fromkeys\b|get\b|has_key\b|items\b|i\
    teritems\b|iterkeys\b|itervalues\b|keys\b|pop\b|popitem\b|setdefault\b\
    ...
    

    DOCTEST_EXAMPLE_RE

    This regular expression is used to find doctest examples in a string. This is copied from the standard Python doctest.py module (after the refactoring in Python 2.4+).

    Value:
    re.compile(r'(?mx)(?P<source>(?:^(?P<indent> *)>>>.*)(?:\n *\.\.\..*)*\
    \n?)(?P<want>(?:(?! *$)(?! *>>>).*$\n?)*)')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docstringparser.DocstringField-class.html0000644000175000017500000003704210750103050027073 0ustar pronovicpronovic epydoc.docstringparser.DocstringField
    Package epydoc :: Module docstringparser :: Class DocstringField
    [hide private]
    [frames] | no frames]

    Class DocstringField

    source code

    A simple docstring field, which can be used to describe specific information about an object, such as its author or its version. Simple docstring fields are fields that take no arguments, and are displayed as simple sections.

    Instance Methods [hide private]
     
    __init__(self, tags, label, plural=None, short=0, multivalue=1, takes_arg=0, varnames=None) source code
    call graph 
     
    __cmp__(self, other) source code
    call graph 
     
    __hash__(self) source code
    call graph 
     
    __repr__(self) source code
    Instance Variables [hide private]
      multivalue
    If true, then multiple values may be given for this field; if false, then this field can only take a single value, and a warning should be issued if it is redefined.
      plural
    The label that should be used to identify this field in the output, if the field contains multiple values.
      short
    If true, then multiple values should be combined into a single comma-delimited list.
      singular
    The label that should be used to identify this field in the output, if the field contains one value.
      tags
    The set of tags that can be used to identify this field.
      takes_arg
    If true, then this field expects an argument; and a separate field section will be constructed for each argument value.
    Instance Variable Details [hide private]

    short

    If true, then multiple values should be combined into a single comma-delimited list. If false, then multiple values should be listed separately in a bulleted list.

    takes_arg

    If true, then this field expects an argument; and a separate field section will be constructed for each argument value. The label (and plural label) should include a '%s' to mark where the argument's string rep should be added.

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.PropertyDoc-class.html0000644000175000017500000011015010750103050024463 0ustar pronovicpronovic epydoc.apidoc.PropertyDoc
    Package epydoc :: Module apidoc :: Class PropertyDoc
    [hide private]
    [frames] | no frames]

    Class PropertyDoc

    source code


    API documentation information about a single property.

    Instance Methods [hide private]
     
    apidoc_links(self, **filters)
    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)
    source code
    call graph 
    bool
    is_detailed(self)
    Does this object deserve a box with extra details?
    source code
    call graph 

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]

    Inherited from ValueDoc: canonical_name, toktree

        Property Access Functions
    RoutineDoc fget = _Sentinel('UNKNOWN')
    API documentation for the property's get function.
    RoutineDoc fset = _Sentinel('UNKNOWN')
    API documentation for the property's set function.
    RoutineDoc fdel = _Sentinel('UNKNOWN')
    API documentation for the property's delete function.
        Information Extracted from Docstrings
    ParsedDocstring type_descr = _Sentinel('UNKNOWN')
    A description of the property's expected type, extracted from its docstring.

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    apidoc_links(self, **filters)

    source code 
    call graph 

    Return a list of all APIDocs that are directly linked from this APIDoc (i.e., are contained or pointed to by one or more of this APIDoc's attributes.)

    Keyword argument filters can be used to selectively exclude certain categories of attribute value. For example, using includes=False will exclude variables that were imported from other modules; and subclasses=False will exclude subclasses. The filter categories currently supported by epydoc are:

    • imports: Imported variables.
    • packages: Containing packages for modules.
    • submodules: Contained submodules for packages.
    • bases: Bases for classes.
    • subclasses: Subclasses for classes.
    • variables: All variables.
    • private: Private variables.
    • overrides: Points from class variables to the variables they override. This filter is False by default.
    Overrides: APIDoc.apidoc_links
    (inherited documentation)

    is_detailed(self)

    source code 
    call graph 

    Does this object deserve a box with extra details?

    Returns: bool
    True if the object needs extra details, else False.
    Overrides: APIDoc.is_detailed
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.latex.LatexWriter-class.html0000644000175000017500000016707710750103050026366 0ustar pronovicpronovic epydoc.docwriter.latex.LatexWriter
    Package epydoc :: Package docwriter :: Module latex :: Class LatexWriter
    [hide private]
    [frames] | no frames]

    Class LatexWriter

    source code

    Nested Classes [hide private]
        Docstring -> LaTeX Conversion
      _LatexDocstringLinker
    Instance Methods [hide private]
     
    __init__(self, docindex, **kwargs) source code
    None
    write(self, directory=None)
    Write the API documentation for the entire project to the given directory.
    source code
     
    _write(self, write_func, directory, filename, *args) source code
    int
    num_files(self)
    Returns: The number of files that this LatexFormatter will generate.
    source code
    None
    _mkdir(self, directory)
    If the given directory does not exist, then attempt to create it.
    source code
        Main Doc File
     
    write_topfile(self, out) source code
     
    write_preamble(self, out) source code
        Chapters
     
    write_module(self, out, doc) source code
     
    write_class(self, out, doc) source code
        Module hierarchy trees
     
    write_module_tree(self, out) source code
     
    write_module_list(self, out, doc) source code
    string
    write_module_tree_item(self, out, doc, depth=0)
    Helper function for write_module_tree and write_module_list.
    source code
        Base class trees
     
    base_tree(self, doc, width=None, linespec=None) source code
     
    _base_name(self, doc) source code
     
    _find_tree_width(self, doc) source code
     
    _base_tree_line(self, doc, width, linespec) source code
        Class List
     
    write_class_list(self, out, doc) source code
     
    write_class_list_line(self, out, var_doc) source code
        Function List
     
    write_func_list(self, out, heading, doc, value_type, seclevel=1) source code
     
    write_func_group(self, out, doc, name, var_docs, grouped_inh_vars) source code
     
    write_func_inheritance_list(self, out, doc, listed_inh_vars) source code
     
    write_func_list_box(self, out, var_doc) source code
     
    function_signature(self, var_doc) source code
     
    func_arg(self, name, default) source code
     
    _arg_name(self, arg) source code
        Variable List
     
    write_var_list(self, out, heading, doc, value_type, seclevel=1) source code
     
    write_var_group(self, out, doc, name, var_docs, grouped_inh_vars) source code
     
    write_var_inheritance_list(self, out, doc, listed_inh_vars) source code
     
    write_var_list_line(self, out, var_doc) source code
     
    write_property_list_line(self, out, var_doc) source code
        Standard Fields
     
    write_standard_fields(self, out, doc) source code
     
    write_standard_field(self, out, doc, field, descrs, arg='') source code
     
    _descrlist(self, items, singular, plural=None, short=0) source code
        Docstring -> LaTeX Conversion
     
    docstring_to_latex(self, docstring, indent=0, breakany=0) source code
        Helpers
     
    write_header(self, out, where) source code
     
    write_start_of(self, out, section_name) source code
     
    section(self, title, depth=0) source code
     
    sectionstar(self, title, depth) source code
     
    doc_kind(self, doc) source code
     
    indexterm(self, doc, pos='only')
    Mark a term or section for inclusion in the index.
    source code
     
    label(self, doc) source code
    str
    get_latex_encoding(self)
    Returns: The LaTeX representation of the selected encoding.
    source code
    Class Variables [hide private]
      PREAMBLE = ['\\documentclass{article}', '\\usepackage{alltt, p...
      HRULE = '\\rule{\\textwidth}{0.5\\fboxrule}\n\n'
      SECTIONS = ['\\part{%s}', '\\chapter{%s}', '\\section{%s}', '\...
      STAR_SECTIONS = ['\\part*{%s}', '\\chapter*{%s}', '\\section*{...
        Function List
      _FUNC_GROUP_HEADER = '\n\\large{\\textbf{\\textit{%s}}}\n\n'
        Variable List
      _VAR_GROUP_HEADER = '\\multicolumn{2}{|l|}{\\textit{%s}}\\\\\n'
        Docstring -> LaTeX Conversion
      _docstring_linker = _LatexDocstringLinker()
        Helpers
      latex_encodings = {'utf-8': 'utf8'}
    Map the Python encoding representation into mismatching LaTeX ones.
    Instance Variables [hide private]
      _encoding
    The Python representation of the encoding.
      class_list
    The list of ClassDocs for the documented classes.
      class_set
    The set of ClassDocs for the documented classes.
    Method Details [hide private]

    write(self, directory=None)

    source code 

    Write the API documentation for the entire project to the given directory.

    Parameters:
    • directory (string) - The directory to which output should be written. If no directory is specified, output will be written to the current directory. If the directory does not exist, it will be created.
    Returns: None
    Raises:
    • OSError - If directory cannot be created,
    • OSError - If any file cannot be created or written to.

    num_files(self)

    source code 
    Returns: int
    The number of files that this LatexFormatter will generate.

    get_latex_encoding(self)

    source code 
    Returns: str
    The LaTeX representation of the selected encoding.

    Class Variable Details [hide private]

    PREAMBLE

    Value:
    ['\\documentclass{article}',
     '\\usepackage{alltt, parskip, fancyhdr, boxedminipage}',
     '\\usepackage{makeidx, multirow, longtable, tocbibind, amssymb}',
     '\\usepackage{fullpage}',
     '\\usepackage[usenames]{color}',
     '\\setlength{\\headheight}{16pt}',
     '\\setlength{\\headsep}{24pt}',
     '\\setlength{\\topmargin}{-\\headsep}',
    ...
    

    SECTIONS

    Value:
    ['\\part{%s}',
     '\\chapter{%s}',
     '\\section{%s}',
     '\\subsection{%s}',
     '\\subsubsection{%s}',
     '\\textbf{%s}']
    

    STAR_SECTIONS

    Value:
    ['\\part*{%s}',
     '\\chapter*{%s}',
     '\\section*{%s}',
     '\\subsection*{%s}',
     '\\subsubsection*{%s}',
     '\\textbf{%s}']
    

    Instance Variable Details [hide private]

    _encoding

    The Python representation of the encoding. Update latex_encodings in case of mismatch between it and the inputenc LaTeX package.


    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.gui-module.html0000644000175000017500000001224710750103050022512 0ustar pronovicpronovic gui

    Module gui


    Classes

    EpydocGUI
    GUILogger

    Functions

    document
    gui

    Variables

    ACTIVEBG_COLOR
    BG_COLOR
    BUILD_PROGRESS
    BUTTON_CONFIG
    CBUTTON_CONFIG
    COLOR_CONFIG
    DEBUG
    DH
    DOWN_GIF
    DW
    DX
    DY
    ENTRYSELECT_COLOR
    ENTRY_CONFIG
    ERROR_COLOR
    GUIERROR_COLOR
    HEADER_COLOR
    IMPORT_PROGRESS
    LEFT_GIF
    LISTBOX_CONFIG
    MESSAGE_COLOR
    PROGRESS_BG
    PROGRESS_COLOR1
    PROGRESS_COLOR2
    PROGRESS_COLOR3
    PROGRESS_HEIGHT
    PROGRESS_WIDTH
    RIGHT_GIF
    SB_CONFIG
    SELECT_COLOR
    SHOWERR_CONFIG
    SHOWMSG_CONFIG
    SHOWWRN_CONFIG
    TEXT_COLOR
    UP_GIF
    WARNING_COLOR
    WRITE_PROGRESS

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph-pysrc.html0000644000175000017500000156742510750103050024645 0ustar pronovicpronovic epydoc.docwriter.dotgraph
    Package epydoc :: Package docwriter :: Module dotgraph
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.dotgraph

       1  # epydoc -- Graph generation 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: dotgraph.py 1663 2007-11-07 15:29:47Z dvarrazzo $ 
       8   
       9  """ 
      10  Render Graphviz directed graphs as images.  Below are some examples. 
      11   
      12  .. importgraph:: 
      13   
      14  .. classtree:: epydoc.apidoc.APIDoc 
      15   
      16  .. packagetree:: epydoc 
      17   
      18  :see: `The Graphviz Homepage 
      19         <http://www.research.att.com/sw/tools/graphviz/>`__ 
      20  """ 
      21  __docformat__ = 'restructuredtext' 
      22   
      23  import re 
      24  import sys 
      25  from epydoc import log 
      26  from epydoc.apidoc import * 
      27  from epydoc.util import * 
      28  from epydoc.compat import * # Backwards compatibility 
      29   
      30  # colors for graphs of APIDocs 
      31  MODULE_BG = '#d8e8ff' 
      32  CLASS_BG = '#d8ffe8' 
      33  SELECTED_BG = '#ffd0d0' 
      34  BASECLASS_BG = '#e0b0a0' 
      35  SUBCLASS_BG = '#e0b0a0' 
      36  ROUTINE_BG = '#e8d0b0' # maybe? 
      37  INH_LINK_COLOR = '#800000' 
      38   
      39  ###################################################################### 
      40  #{ Dot Graphs 
      41  ###################################################################### 
      42   
      43  DOT_COMMAND = 'dot' 
      44  """The command that should be used to spawn dot""" 
      45   
    
    46 -class DotGraph:
    47 """ 48 A ``dot`` directed graph. The contents of the graph are 49 constructed from the following instance variables: 50 51 - `nodes`: A list of `DotGraphNode`\\s, encoding the nodes 52 that are present in the graph. Each node is characterized 53 a set of attributes, including an optional label. 54 - `edges`: A list of `DotGraphEdge`\\s, encoding the edges 55 that are present in the graph. Each edge is characterized 56 by a set of attributes, including an optional label. 57 - `node_defaults`: Default attributes for nodes. 58 - `edge_defaults`: Default attributes for edges. 59 - `body`: A string that is appended as-is in the body of 60 the graph. This can be used to build more complex dot 61 graphs. 62 63 The `link()` method can be used to resolve crossreference links 64 within the graph. In particular, if the 'href' attribute of any 65 node or edge is assigned a value of the form ``<name>``, then it 66 will be replaced by the URL of the object with that name. This 67 applies to the `body` as well as the `nodes` and `edges`. 68 69 To render the graph, use the methods `write()` and `render()`. 70 Usually, you should call `link()` before you render the graph. 71 """ 72 _uids = set() 73 """A set of all uids that that have been generated, used to ensure 74 that each new graph has a unique uid.""" 75 76 DEFAULT_NODE_DEFAULTS={'fontsize':10, 'fontname': 'Helvetica'} 77 DEFAULT_EDGE_DEFAULTS={'fontsize':10, 'fontname': 'Helvetica'} 78
    79 - def __init__(self, title, body='', node_defaults=None, 80 edge_defaults=None, caption=None):
    81 """ 82 Create a new `DotGraph`. 83 """ 84 self.title = title 85 """The title of the graph.""" 86 87 self.caption = caption 88 """A caption for the graph.""" 89 90 self.nodes = [] 91 """A list of the nodes that are present in the graph. 92 93 :type: ``list`` of `DotGraphNode`""" 94 95 self.edges = [] 96 """A list of the edges that are present in the graph. 97 98 :type: ``list`` of `DotGraphEdge`""" 99 100 self.body = body 101 """A string that should be included as-is in the body of the 102 graph. 103 104 :type: ``str``""" 105 106 self.node_defaults = node_defaults or self.DEFAULT_NODE_DEFAULTS 107 """Default attribute values for nodes.""" 108 109 self.edge_defaults = edge_defaults or self.DEFAULT_EDGE_DEFAULTS 110 """Default attribute values for edges.""" 111 112 self.uid = re.sub(r'\W', '_', title).lower() 113 """A unique identifier for this graph. This can be used as a 114 filename when rendering the graph. No two `DotGraph`\s will 115 have the same uid.""" 116 117 # Encode the title, if necessary. 118 if isinstance(self.title, unicode): 119 self.title = self.title.encode('ascii', 'xmlcharrefreplace') 120 121 # Make sure the UID isn't too long. 122 self.uid = self.uid[:30] 123 124 # Make sure the UID is unique 125 if self.uid in self._uids: 126 n = 2 127 while ('%s_%s' % (self.uid, n)) in self._uids: n += 1 128 self.uid = '%s_%s' % (self.uid, n) 129 self._uids.add(self.uid)
    130
    131 - def to_html(self, image_file, image_url, center=True):
    132 """ 133 Return the HTML code that should be uesd to display this graph 134 (including a client-side image map). 135 136 :param image_url: The URL of the image file for this graph; 137 this should be generated separately with the `write()` method. 138 """ 139 # If dotversion >1.8.10, then we can generate the image and 140 # the cmapx with a single call to dot. Otherwise, we need to 141 # run dot twice. 142 if get_dot_version() > [1,8,10]: 143 cmapx = self._run_dot('-Tgif', '-o%s' % image_file, '-Tcmapx') 144 if cmapx is None: return '' # failed to render 145 else: 146 if not self.write(image_file): 147 return '' # failed to render 148 cmapx = self.render('cmapx') or '' 149 150 # Decode the cmapx (dot uses utf-8) 151 try: 152 cmapx = cmapx.decode('utf-8') 153 except UnicodeDecodeError: 154 log.debug('%s: unable to decode cmapx from dot; graph will ' 155 'not have clickable regions' % image_file) 156 cmapx = '' 157 158 title = plaintext_to_html(self.title or '') 159 caption = plaintext_to_html(self.caption or '') 160 if title or caption: 161 css_class = 'graph-with-title' 162 else: 163 css_class = 'graph-without-title' 164 if len(title)+len(caption) > 80: 165 title_align = 'left' 166 table_width = ' width="600"' 167 else: 168 title_align = 'center' 169 table_width = '' 170 171 if center: s = '<center>' 172 if title or caption: 173 s += ('<table border="0" cellpadding="0" cellspacing="0" ' 174 'class="graph"%s>\n <tr><td align="center">\n' % 175 table_width) 176 s += (' %s\n <img src="%s" alt=%r usemap="#%s" ' 177 'ismap="ismap" class="%s" />\n' % 178 (cmapx.strip(), image_url, title, self.uid, css_class)) 179 if title or caption: 180 s += ' </td></tr>\n <tr><td align=%r>\n' % title_align 181 if title: 182 s += '<span class="graph-title">%s</span>' % title 183 if title and caption: 184 s += ' -- ' 185 if caption: 186 s += '<span class="graph-caption">%s</span>' % caption 187 s += '\n </td></tr>\n</table><br />' 188 if center: s += '</center>' 189 return s
    190 211 self.body = re.sub("href\s*=\s*['\"]?<([\w\.]+)>['\"]?\s*(,?)", 212 subfunc, self.body)
    213 222
    223 - def write(self, filename, language='gif'):
    224 """ 225 Render the graph using the output format `language`, and write 226 the result to `filename`. 227 228 :return: True if rendering was successful. 229 """ 230 result = self._run_dot('-T%s' % language, 231 '-o%s' % filename) 232 # Decode into unicode, if necessary. 233 if language == 'cmapx' and result is not None: 234 result = result.decode('utf-8') 235 return (result is not None)
    236
    237 - def render(self, language='gif'):
    238 """ 239 Use the ``dot`` command to render this graph, using the output 240 format `language`. Return the result as a string, or ``None`` 241 if the rendering failed. 242 """ 243 return self._run_dot('-T%s' % language)
    244
    245 - def _run_dot(self, *options):
    246 try: 247 result, err = run_subprocess((DOT_COMMAND,)+options, 248 self.to_dotfile()) 249 if err: log.warning("Graphviz dot warning(s):\n%s" % err) 250 except OSError, e: 251 log.warning("Unable to render Graphviz dot graph:\n%s" % e) 252 #log.debug(self.to_dotfile()) 253 return None 254 255 return result
    256
    257 - def to_dotfile(self):
    258 """ 259 Return the string contents of the dot file that should be used 260 to render this graph. 261 """ 262 lines = ['digraph %s {' % self.uid, 263 'node [%s]' % ','.join(['%s="%s"' % (k,v) for (k,v) 264 in self.node_defaults.items()]), 265 'edge [%s]' % ','.join(['%s="%s"' % (k,v) for (k,v) 266 in self.edge_defaults.items()])] 267 if self.body: 268 lines.append(self.body) 269 lines.append('/* Nodes */') 270 for node in self.nodes: 271 lines.append(node.to_dotfile()) 272 lines.append('/* Edges */') 273 for edge in self.edges: 274 lines.append(edge.to_dotfile()) 275 lines.append('}') 276 277 # Default dot input encoding is UTF-8 278 return u'\n'.join(lines).encode('utf-8')
    279
    280 -class DotGraphNode:
    281 _next_id = 0
    282 - def __init__(self, label=None, html_label=None, **attribs):
    283 if label is not None and html_label is not None: 284 raise ValueError('Use label or html_label, not both.') 285 if label is not None: attribs['label'] = label 286 self._html_label = html_label 287 self._attribs = attribs 288 self.id = self.__class__._next_id 289 self.__class__._next_id += 1 290 self.port = None
    291
    292 - def __getitem__(self, attr):
    293 return self._attribs[attr]
    294
    295 - def __setitem__(self, attr, val):
    296 if attr == 'html_label': 297 self._attribs.pop('label') 298 self._html_label = val 299 else: 300 if attr == 'label': self._html_label = None 301 self._attribs[attr] = val
    302
    303 - def to_dotfile(self):
    304 """ 305 Return the dot commands that should be used to render this node. 306 """ 307 attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items() 308 if v is not None] 309 if self._html_label: 310 attribs.insert(0, 'label=<%s>' % (self._html_label,)) 311 if attribs: attribs = ' [%s]' % (','.join(attribs)) 312 return 'node%d%s' % (self.id, attribs)
    313
    314 -class DotGraphEdge:
    315 - def __init__(self, start, end, label=None, **attribs):
    316 """ 317 :type start: `DotGraphNode` 318 :type end: `DotGraphNode` 319 """ 320 assert isinstance(start, DotGraphNode) 321 assert isinstance(end, DotGraphNode) 322 if label is not None: attribs['label'] = label 323 self.start = start #: :type: `DotGraphNode` 324 self.end = end #: :type: `DotGraphNode` 325 self._attribs = attribs
    326
    327 - def __getitem__(self, attr):
    328 return self._attribs[attr]
    329
    330 - def __setitem__(self, attr, val):
    331 self._attribs[attr] = val
    332
    333 - def to_dotfile(self):
    334 """ 335 Return the dot commands that should be used to render this edge. 336 """ 337 # Set head & tail ports, if the nodes have preferred ports. 338 attribs = self._attribs.copy() 339 if (self.start.port is not None and 'headport' not in attribs): 340 attribs['headport'] = self.start.port 341 if (self.end.port is not None and 'tailport' not in attribs): 342 attribs['tailport'] = self.end.port 343 # Convert attribs to a string 344 attribs = ','.join(['%s="%s"' % (k,v) for (k,v) in attribs.items() 345 if v is not None]) 346 if attribs: attribs = ' [%s]' % attribs 347 # Return the dotfile edge. 348 return 'node%d -> node%d%s' % (self.start.id, self.end.id, attribs)
    349 350 ###################################################################### 351 #{ Specialized Nodes for UML Graphs 352 ###################################################################### 353
    354 -class DotGraphUmlClassNode(DotGraphNode):
    355 """ 356 A specialized dot graph node used to display `ClassDoc`\s using 357 UML notation. The node is rendered as a table with three cells: 358 the top cell contains the class name; the middle cell contains a 359 list of attributes; and the bottom cell contains a list of 360 operations:: 361 362 +-------------+ 363 | ClassName | 364 +-------------+ 365 | x: int | 366 | ... | 367 +-------------+ 368 | f(self, x) | 369 | ... | 370 +-------------+ 371 372 `DotGraphUmlClassNode`\s may be *collapsed*, in which case they are 373 drawn as a simple box containing the class name:: 374 375 +-------------+ 376 | ClassName | 377 +-------------+ 378 379 Attributes with types corresponding to documented classes can 380 optionally be converted into edges, using `link_attributes()`. 381 382 :todo: Add more options? 383 - show/hide operation signature 384 - show/hide operation signature types 385 - show/hide operation signature return type 386 - show/hide attribute types 387 - use qualifiers 388 """ 389
    390 - def __init__(self, class_doc, linker, context, collapsed=False, 391 bgcolor=CLASS_BG, **options):
    392 """ 393 Create a new `DotGraphUmlClassNode` based on the class 394 `class_doc`. 395 396 :Parameters: 397 `linker` : `markup.DocstringLinker` 398 Used to look up URLs for classes. 399 `context` : `APIDoc` 400 The context in which this node will be drawn; dotted 401 names will be contextualized to this context. 402 `collapsed` : ``bool`` 403 If true, then display this node as a simple box. 404 `bgcolor` : ```str``` 405 The background color for this node. 406 `options` : ``dict`` 407 A set of options used to control how the node should 408 be displayed. 409 410 :Keywords: 411 - `show_private_vars`: If false, then private variables 412 are filtered out of the attributes & operations lists. 413 (Default: *False*) 414 - `show_magic_vars`: If false, then magic variables 415 (such as ``__init__`` and ``__add__``) are filtered out of 416 the attributes & operations lists. (Default: *True*) 417 - `show_inherited_vars`: If false, then inherited variables 418 are filtered out of the attributes & operations lists. 419 (Default: *False*) 420 - `max_attributes`: The maximum number of attributes that 421 should be listed in the attribute box. If the class has 422 more than this number of attributes, some will be 423 ellided. Ellipsis is marked with ``'...'``. 424 - `max_operations`: The maximum number of operations that 425 should be listed in the operation box. 426 - `add_nodes_for_linked_attributes`: If true, then 427 `link_attributes()` will create new a collapsed node for 428 the types of a linked attributes if no node yet exists for 429 that type. 430 """ 431 if not isinstance(class_doc, ClassDoc): 432 raise TypeError('Expected a ClassDoc as 1st argument') 433 434 self.class_doc = class_doc 435 """The class represented by this node.""" 436 437 self.linker = linker 438 """Used to look up URLs for classes.""" 439 440 self.context = context 441 """The context in which the node will be drawn.""" 442 443 self.bgcolor = bgcolor 444 """The background color of the node.""" 445 446 self.options = options 447 """Options used to control how the node is displayed.""" 448 449 self.collapsed = collapsed 450 """If true, then draw this node as a simple box.""" 451 452 self.attributes = [] 453 """The list of VariableDocs for attributes""" 454 455 self.operations = [] 456 """The list of VariableDocs for operations""" 457 458 self.qualifiers = [] 459 """List of (key_label, port) tuples.""" 460 461 self.edges = [] 462 """List of edges used to represent this node's attributes. 463 These should not be added to the `DotGraph`; this node will 464 generate their dotfile code directly.""" 465 466 # Initialize operations & attributes lists. 467 show_private = options.get('show_private_vars', False) 468 show_magic = options.get('show_magic_vars', True) 469 show_inherited = options.get('show_inherited_vars', False) 470 for var in class_doc.sorted_variables: 471 name = var.canonical_name[-1] 472 if ((not show_private and var.is_public == False) or 473 (not show_magic and re.match('__\w+__$', name)) or 474 (not show_inherited and var.container != class_doc)): 475 pass 476 elif isinstance(var.value, RoutineDoc): 477 self.operations.append(var) 478 else: 479 self.attributes.append(var) 480 481 # Initialize our dot node settings. 482 tooltip = self._summary(class_doc) 483 if tooltip: 484 # dot chokes on a \n in the attribute... 485 tooltip = " ".join(tooltip.split()) 486 else: 487 tooltip = class_doc.canonical_name 488 DotGraphNode.__init__(self, tooltip=tooltip, 489 width=0, height=0, shape='plaintext', 490 href=linker.url_for(class_doc) or NOOP_URL)
    491 492 #///////////////////////////////////////////////////////////////// 493 #{ Attribute Linking 494 #///////////////////////////////////////////////////////////////// 495 496 SIMPLE_TYPE_RE = re.compile( 497 r'^([\w\.]+)$') 498 """A regular expression that matches descriptions of simple types.""" 499 500 COLLECTION_TYPE_RE = re.compile( 501 r'^(list|set|sequence|tuple|collection) of ([\w\.]+)$') 502 """A regular expression that matches descriptions of collection types.""" 503 504 MAPPING_TYPE_RE = re.compile( 505 r'^(dict|dictionary|map|mapping) from ([\w\.]+) to ([\w\.]+)$') 506 """A regular expression that matches descriptions of mapping types.""" 507 508 MAPPING_TO_COLLECTION_TYPE_RE = re.compile( 509 r'^(dict|dictionary|map|mapping) from ([\w\.]+) to ' 510 r'(list|set|sequence|tuple|collection) of ([\w\.]+)$') 511 """A regular expression that matches descriptions of mapping types 512 whose value type is a collection.""" 513 514 OPTIONAL_TYPE_RE = re.compile( 515 r'^(None or|optional) ([\w\.]+)$|^([\w\.]+) or None$') 516 """A regular expression that matches descriptions of optional types.""" 517 553 601
    602 - def _add_attribute_edge(self, var, nodes, type_str, **attribs):
    603 """ 604 Helper for `link_attributes()`: try to add an edge for the 605 given attribute variable `var`. Return ``True`` if 606 successful. 607 """ 608 # Use the type string to look up a corresponding ValueDoc. 609 type_doc = self.linker.docindex.find(type_str, var) 610 if not type_doc: return False 611 612 # Make sure the type is a class. 613 if not isinstance(type_doc, ClassDoc): return False 614 615 # Get the type ValueDoc's node. If it doesn't have one (and 616 # add_nodes_for_linked_attributes=True), then create it. 617 type_node = nodes.get(type_doc) 618 if not type_node: 619 if self.options.get('add_nodes_for_linked_attributes', True): 620 type_node = DotGraphUmlClassNode(type_doc, self.linker, 621 self.context, collapsed=True) 622 nodes[type_doc] = type_node 623 else: 624 return False 625 626 # Add an edge from self to the target type node. 627 # [xx] should I set constraint=false here? 628 attribs.setdefault('headport', 'body') 629 attribs.setdefault('tailport', 'body') 630 url = self.linker.url_for(var) or NOOP_URL 631 self.edges.append(DotGraphEdge(self, type_node, label=var.name, 632 arrowhead='open', href=url, 633 tooltip=var.canonical_name, labeldistance=1.5, 634 **attribs)) 635 return True
    636 637 #///////////////////////////////////////////////////////////////// 638 #{ Helper Methods 639 #/////////////////////////////////////////////////////////////////
    640 - def _summary(self, api_doc):
    641 """Return a plaintext summary for `api_doc`""" 642 if not isinstance(api_doc, APIDoc): return '' 643 if api_doc.summary in (None, UNKNOWN): return '' 644 summary = api_doc.summary.to_plaintext(None).strip() 645 return plaintext_to_html(summary)
    646 647 _summary = classmethod(_summary) 648
    649 - def _type_descr(self, api_doc):
    650 """Return a plaintext type description for `api_doc`""" 651 if not hasattr(api_doc, 'type_descr'): return '' 652 if api_doc.type_descr in (None, UNKNOWN): return '' 653 type_descr = api_doc.type_descr.to_plaintext(self.linker).strip() 654 return plaintext_to_html(type_descr)
    655
    656 - def _tooltip(self, var_doc):
    657 """Return a tooltip for `var_doc`.""" 658 return (self._summary(var_doc) or 659 self._summary(var_doc.value) or 660 var_doc.canonical_name)
    661 662 #///////////////////////////////////////////////////////////////// 663 #{ Rendering 664 #///////////////////////////////////////////////////////////////// 665
    666 - def _attribute_cell(self, var_doc):
    667 # Construct the label 668 label = var_doc.name 669 type_descr = (self._type_descr(var_doc) or 670 self._type_descr(var_doc.value)) 671 if type_descr: label += ': %s' % type_descr 672 # Get the URL 673 url = self.linker.url_for(var_doc) or NOOP_URL 674 # Construct & return the pseudo-html code 675 return self._ATTRIBUTE_CELL % (url, self._tooltip(var_doc), label)
    676
    677 - def _operation_cell(self, var_doc):
    678 """ 679 :todo: do 'word wrapping' on the signature, by starting a new 680 row in the table, if necessary. How to indent the new 681 line? Maybe use align=right? I don't think dot has a 682 &nbsp;. 683 :todo: Optionally add return type info? 684 """ 685 # Construct the label (aka function signature) 686 func_doc = var_doc.value 687 args = [self._operation_arg(n, d, func_doc) for (n, d) 688 in zip(func_doc.posargs, func_doc.posarg_defaults)] 689 args = [plaintext_to_html(arg) for arg in args] 690 if func_doc.vararg: args.append('*'+func_doc.vararg) 691 if func_doc.kwarg: args.append('**'+func_doc.kwarg) 692 label = '%s(%s)' % (var_doc.name, ', '.join(args)) 693 # Get the URL 694 url = self.linker.url_for(var_doc) or NOOP_URL 695 # Construct & return the pseudo-html code 696 return self._OPERATION_CELL % (url, self._tooltip(var_doc), label)
    697
    698 - def _operation_arg(self, name, default, func_doc):
    699 """ 700 :todo: Handle tuple args better 701 :todo: Optionally add type info? 702 """ 703 if default is None: 704 return '%s' % name 705 else: 706 pyval_repr = default.summary_pyval_repr().to_plaintext(None) 707 return '%s=%s' % (name, pyval_repr)
    708
    709 - def _qualifier_cell(self, key_label, port):
    710 return self._QUALIFIER_CELL % (port, self.bgcolor, key_label)
    711 712 #: args: (url, tooltip, label) 713 _ATTRIBUTE_CELL = ''' 714 <TR><TD ALIGN="LEFT" HREF="%s" TOOLTIP="%s">%s</TD></TR> 715 ''' 716 717 #: args: (url, tooltip, label) 718 _OPERATION_CELL = ''' 719 <TR><TD ALIGN="LEFT" HREF="%s" TOOLTIP="%s">%s</TD></TR> 720 ''' 721 722 #: args: (port, bgcolor, label) 723 _QUALIFIER_CELL = ''' 724 <TR><TD VALIGN="BOTTOM" PORT="%s" BGCOLOR="%s" BORDER="1">%s</TD></TR> 725 ''' 726 727 _QUALIFIER_DIV = ''' 728 <TR><TD VALIGN="BOTTOM" HEIGHT="10" WIDTH="10" FIXEDSIZE="TRUE"></TD></TR> 729 ''' 730 731 #: Args: (rowspan, bgcolor, classname, attributes, operations, qualifiers) 732 _LABEL = ''' 733 <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" CELLPADDING="0"> 734 <TR><TD ROWSPAN="%s"> 735 <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" 736 CELLPADDING="0" PORT="body" BGCOLOR="%s"> 737 <TR><TD>%s</TD></TR> 738 <TR><TD><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0"> 739 %s</TABLE></TD></TR> 740 <TR><TD><TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0"> 741 %s</TABLE></TD></TR> 742 </TABLE> 743 </TD></TR> 744 %s 745 </TABLE>''' 746 747 _COLLAPSED_LABEL = ''' 748 <TABLE CELLBORDER="0" BGCOLOR="%s" PORT="body"> 749 <TR><TD>%s</TD></TR> 750 </TABLE>''' 751
    752 - def _get_html_label(self):
    753 # Get the class name & contextualize it. 754 classname = self.class_doc.canonical_name 755 classname = classname.contextualize(self.context.canonical_name) 756 757 # If we're collapsed, display the node as a single box. 758 if self.collapsed: 759 return self._COLLAPSED_LABEL % (self.bgcolor, classname) 760 761 # Construct the attribute list. (If it's too long, truncate) 762 attrib_cells = [self._attribute_cell(a) for a in self.attributes] 763 max_attributes = self.options.get('max_attributes', 15) 764 if len(attrib_cells) == 0: 765 attrib_cells = ['<TR><TD></TD></TR>'] 766 elif len(attrib_cells) > max_attributes: 767 attrib_cells[max_attributes-2:-1] = ['<TR><TD>...</TD></TR>'] 768 attributes = ''.join(attrib_cells) 769 770 # Construct the operation list. (If it's too long, truncate) 771 oper_cells = [self._operation_cell(a) for a in self.operations] 772 max_operations = self.options.get('max_operations', 15) 773 if len(oper_cells) == 0: 774 oper_cells = ['<TR><TD></TD></TR>'] 775 elif len(oper_cells) > max_operations: 776 oper_cells[max_operations-2:-1] = ['<TR><TD>...</TD></TR>'] 777 operations = ''.join(oper_cells) 778 779 # Construct the qualifier list & determine the rowspan. 780 if self.qualifiers: 781 rowspan = len(self.qualifiers)*2+2 782 div = self._QUALIFIER_DIV 783 qualifiers = div+div.join([self._qualifier_cell(l,p) for 784 (l,p) in self.qualifiers])+div 785 else: 786 rowspan = 1 787 qualifiers = '' 788 789 # Put it all together. 790 return self._LABEL % (rowspan, self.bgcolor, classname, 791 attributes, operations, qualifiers)
    792
    793 - def to_dotfile(self):
    794 attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items()] 795 attribs.append('label=<%s>' % self._get_html_label()) 796 s = 'node%d%s' % (self.id, ' [%s]' % (','.join(attribs))) 797 if not self.collapsed: 798 for edge in self.edges: 799 s += '\n' + edge.to_dotfile() 800 return s
    801
    802 -class DotGraphUmlModuleNode(DotGraphNode):
    803 """ 804 A specialized dot grah node used to display `ModuleDoc`\s using 805 UML notation. Simple module nodes look like:: 806 807 .----. 808 +------------+ 809 | modulename | 810 +------------+ 811 812 Packages nodes are drawn with their modules & subpackages nested 813 inside:: 814 815 .----. 816 +----------------------------------------+ 817 | packagename | 818 | | 819 | .----. .----. .----. | 820 | +---------+ +---------+ +---------+ | 821 | | module1 | | module2 | | module3 | | 822 | +---------+ +---------+ +---------+ | 823 | | 824 +----------------------------------------+ 825 826 """
    827 - def __init__(self, module_doc, linker, context, collapsed=False, 828 excluded_submodules=(), **options):
    829 self.module_doc = module_doc 830 self.linker = linker 831 self.context = context 832 self.collapsed = collapsed 833 self.options = options 834 self.excluded_submodules = excluded_submodules 835 DotGraphNode.__init__(self, shape='plaintext', 836 href=linker.url_for(module_doc) or NOOP_URL, 837 tooltip=module_doc.canonical_name)
    838 839 #: Expects: (color, color, url, tooltip, body) 840 _MODULE_LABEL = ''' 841 <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" ALIGN="LEFT"> 842 <TR><TD ALIGN="LEFT" VALIGN="BOTTOM" HEIGHT="8" WIDTH="16" 843 FIXEDSIZE="true" BGCOLOR="%s" BORDER="1" PORT="tab"></TD></TR> 844 <TR><TD ALIGN="LEFT" VALIGN="TOP" BGCOLOR="%s" BORDER="1" WIDTH="20" 845 PORT="body" HREF="%s" TOOLTIP="%s">%s</TD></TR> 846 </TABLE>''' 847 848 #: Expects: (name, body_rows) 849 _NESTED_BODY = ''' 850 <TABLE BORDER="0" CELLBORDER="0" CELLPADDING="0" CELLSPACING="0"> 851 <TR><TD ALIGN="LEFT">%s</TD></TR> 852 %s 853 </TABLE>''' 854 855 #: Expects: (cells,) 856 _NESTED_BODY_ROW = ''' 857 <TR><TD> 858 <TABLE BORDER="0" CELLBORDER="0"><TR>%s</TR></TABLE> 859 </TD></TR>''' 860
    861 - def _get_html_label(self, package):
    862 """ 863 :Return: (label, depth, width) where: 864 865 - ``label`` is the HTML label 866 - ``depth`` is the depth of the package tree (for coloring) 867 - ``width`` is the max width of the HTML label, roughly in 868 units of characters. 869 """ 870 MAX_ROW_WIDTH = 80 # unit is roughly characters. 871 pkg_name = package.canonical_name 872 pkg_url = self.linker.url_for(package) or NOOP_URL 873 874 if (not package.is_package or len(package.submodules) == 0 or 875 self.collapsed): 876 pkg_color = self._color(package, 1) 877 label = self._MODULE_LABEL % (pkg_color, pkg_color, 878 pkg_url, pkg_name, pkg_name[-1]) 879 return (label, 1, len(pkg_name[-1])+3) 880 881 # Get the label for each submodule, and divide them into rows. 882 row_list = [''] 883 row_width = 0 884 max_depth = 0 885 max_row_width = len(pkg_name[-1])+3 886 for submodule in package.submodules: 887 if submodule in self.excluded_submodules: continue 888 # Get the submodule's label. 889 label, depth, width = self._get_html_label(submodule) 890 # Check if we should start a new row. 891 if row_width > 0 and width+row_width > MAX_ROW_WIDTH: 892 row_list.append('') 893 row_width = 0 894 # Add the submodule's label to the row. 895 row_width += width 896 row_list[-1] += '<TD ALIGN="LEFT">%s</TD>' % label 897 # Update our max's. 898 max_depth = max(depth, max_depth) 899 max_row_width = max(row_width, max_row_width) 900 901 # Figure out which color to use. 902 pkg_color = self._color(package, depth+1) 903 904 # Assemble & return the label. 905 rows = ''.join([self._NESTED_BODY_ROW % r for r in row_list]) 906 body = self._NESTED_BODY % (pkg_name, rows) 907 label = self._MODULE_LABEL % (pkg_color, pkg_color, 908 pkg_url, pkg_name, body) 909 return label, max_depth+1, max_row_width
    910 911 _COLOR_DIFF = 24
    912 - def _color(self, package, depth):
    913 if package == self.context: return SELECTED_BG 914 else: 915 # Parse the base color. 916 if re.match(MODULE_BG, 'r#[0-9a-fA-F]{6}$'): 917 base = int(MODULE_BG[1:], 16) 918 else: 919 base = int('d8e8ff', 16) 920 red = (base & 0xff0000) >> 16 921 green = (base & 0x00ff00) >> 8 922 blue = (base & 0x0000ff) 923 # Make it darker with each level of depth. (but not *too* 924 # dark -- package name needs to be readable) 925 red = max(64, red-(depth-1)*self._COLOR_DIFF) 926 green = max(64, green-(depth-1)*self._COLOR_DIFF) 927 blue = max(64, blue-(depth-1)*self._COLOR_DIFF) 928 # Convert it back to a color string 929 return '#%06x' % ((red<<16)+(green<<8)+blue)
    930
    931 - def to_dotfile(self):
    932 attribs = ['%s="%s"' % (k,v) for (k,v) in self._attribs.items()] 933 label, depth, width = self._get_html_label(self.module_doc) 934 attribs.append('label=<%s>' % label) 935 return 'node%d%s' % (self.id, ' [%s]' % (','.join(attribs)))
    936 937 938 939 ###################################################################### 940 #{ Graph Generation Functions 941 ###################################################################### 942
    943 -def package_tree_graph(packages, linker, context=None, **options):
    944 """ 945 Return a `DotGraph` that graphically displays the package 946 hierarchies for the given packages. 947 """ 948 if options.get('style', 'uml') == 'uml': # default to uml style? 949 if get_dot_version() >= [2]: 950 return uml_package_tree_graph(packages, linker, context, 951 **options) 952 elif 'style' in options: 953 log.warning('UML style package trees require dot version 2.0+') 954 955 graph = DotGraph('Package Tree for %s' % name_list(packages, context), 956 body='ranksep=.3\n;nodesep=.1\n', 957 edge_defaults={'dir':'none'}) 958 959 # Options 960 if options.get('dir', 'TB') != 'TB': # default: top-to-bottom 961 graph.body += 'rankdir=%s\n' % options.get('dir', 'TB') 962 963 # Get a list of all modules in the package. 964 queue = list(packages) 965 modules = set(packages) 966 for module in queue: 967 queue.extend(module.submodules) 968 modules.update(module.submodules) 969 970 # Add a node for each module. 971 nodes = add_valdoc_nodes(graph, modules, linker, context) 972 973 # Add an edge for each package/submodule relationship. 974 for module in modules: 975 for submodule in module.submodules: 976 graph.edges.append(DotGraphEdge(nodes[module], nodes[submodule], 977 headport='tab')) 978 979 return graph
    980
    981 -def uml_package_tree_graph(packages, linker, context=None, **options):
    982 """ 983 Return a `DotGraph` that graphically displays the package 984 hierarchies for the given packages as a nested set of UML 985 symbols. 986 """ 987 graph = DotGraph('Package Tree for %s' % name_list(packages, context)) 988 # Remove any packages whose containers are also in the list. 989 root_packages = [] 990 for package1 in packages: 991 for package2 in packages: 992 if (package1 is not package2 and 993 package2.canonical_name.dominates(package1.canonical_name)): 994 break 995 else: 996 root_packages.append(package1) 997 # If the context is a variable, then get its value. 998 if isinstance(context, VariableDoc) and context.value is not UNKNOWN: 999 context = context.value 1000 # Return a graph with one node for each root package. 1001 for package in root_packages: 1002 graph.nodes.append(DotGraphUmlModuleNode(package, linker, context)) 1003 return graph
    1004 1005 ######################################################################
    1006 -def class_tree_graph(bases, linker, context=None, **options):
    1007 """ 1008 Return a `DotGraph` that graphically displays the class 1009 hierarchy for the given classes. Options: 1010 1011 - exclude 1012 - dir: LR|RL|BT requests a left-to-right, right-to-left, or 1013 bottom-to- top, drawing. (corresponds to the dot option 1014 'rankdir' 1015 """ 1016 if isinstance(bases, ClassDoc): bases = [bases] 1017 graph = DotGraph('Class Hierarchy for %s' % name_list(bases, context), 1018 body='ranksep=0.3\n', 1019 edge_defaults={'sametail':True, 'dir':'none'}) 1020 1021 # Options 1022 if options.get('dir', 'TB') != 'TB': # default: top-down 1023 graph.body += 'rankdir=%s\n' % options.get('dir', 'TB') 1024 exclude = options.get('exclude', ()) 1025 1026 # Find all superclasses & subclasses of the given classes. 1027 classes = set(bases) 1028 queue = list(bases) 1029 for cls in queue: 1030 if isinstance(cls, ClassDoc): 1031 if cls.subclasses not in (None, UNKNOWN): 1032 subclasses = cls.subclasses 1033 if exclude: 1034 subclasses = [d for d in subclasses if d not in exclude] 1035 queue.extend(subclasses) 1036 classes.update(subclasses) 1037 queue = list(bases) 1038 for cls in queue: 1039 if isinstance(cls, ClassDoc): 1040 if cls.bases not in (None, UNKNOWN): 1041 bases = cls.bases 1042 if exclude: 1043 bases = [d for d in bases if d not in exclude] 1044 queue.extend(bases) 1045 classes.update(bases) 1046 1047 # Add a node for each cls. 1048 classes = [d for d in classes if isinstance(d, ClassDoc) 1049 if d.pyval is not object] 1050 nodes = add_valdoc_nodes(graph, classes, linker, context) 1051 1052 # Add an edge for each package/subclass relationship. 1053 edges = set() 1054 for cls in classes: 1055 for subcls in cls.subclasses: 1056 if cls in nodes and subcls in nodes: 1057 edges.add((nodes[cls], nodes[subcls])) 1058 graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] 1059 1060 return graph
    1061 1062 ######################################################################
    1063 -def uml_class_tree_graph(class_doc, linker, context=None, **options):
    1064 """ 1065 Return a `DotGraph` that graphically displays the class hierarchy 1066 for the given class, using UML notation. Options: 1067 1068 - max_attributes 1069 - max_operations 1070 - show_private_vars 1071 - show_magic_vars 1072 - link_attributes 1073 """ 1074 nodes = {} # ClassDoc -> DotGraphUmlClassNode 1075 exclude = options.get('exclude', ()) 1076 1077 # Create nodes for class_doc and all its bases. 1078 for cls in class_doc.mro(): 1079 if cls.pyval is object: continue # don't include `object`. 1080 if cls in exclude: break # stop if we get to an excluded class. 1081 if cls == class_doc: color = SELECTED_BG 1082 else: color = BASECLASS_BG 1083 nodes[cls] = DotGraphUmlClassNode(cls, linker, context, 1084 show_inherited_vars=False, 1085 collapsed=False, bgcolor=color) 1086 1087 # Create nodes for all class_doc's subclasses. 1088 queue = [class_doc] 1089 for cls in queue: 1090 if (isinstance(cls, ClassDoc) and 1091 cls.subclasses not in (None, UNKNOWN)): 1092 for subcls in cls.subclasses: 1093 subcls_name = subcls.canonical_name[-1] 1094 if subcls not in nodes and subcls not in exclude: 1095 queue.append(subcls) 1096 nodes[subcls] = DotGraphUmlClassNode( 1097 subcls, linker, context, collapsed=True, 1098 bgcolor=SUBCLASS_BG) 1099 1100 # Only show variables in the class where they're defined for 1101 # *class_doc*. 1102 mro = class_doc.mro() 1103 for name, var in class_doc.variables.items(): 1104 i = mro.index(var.container) 1105 for base in mro[i+1:]: 1106 if base.pyval is object: continue # don't include `object`. 1107 overridden_var = base.variables.get(name) 1108 if overridden_var and overridden_var.container == base: 1109 try: 1110 if isinstance(overridden_var.value, RoutineDoc): 1111 nodes[base].operations.remove(overridden_var) 1112 else: 1113 nodes[base].attributes.remove(overridden_var) 1114 except ValueError: 1115 pass # var is filtered (eg private or magic) 1116 1117 # Keep track of which nodes are part of the inheritance graph 1118 # (since link_attributes might add new nodes) 1119 inheritance_nodes = set(nodes.values()) 1120 1121 # Turn attributes into links. 1122 if options.get('link_attributes', True): 1123 for node in nodes.values(): 1124 node.link_attributes(nodes) 1125 # Make sure that none of the new attribute edges break the 1126 # rank ordering assigned by inheritance. 1127 for edge in node.edges: 1128 if edge.end in inheritance_nodes: 1129 edge['constraint'] = 'False' 1130 1131 # Construct the graph. 1132 graph = DotGraph('UML class diagram for %s' % class_doc.canonical_name, 1133 body='ranksep=.2\n;nodesep=.3\n') 1134 graph.nodes = nodes.values() 1135 1136 # Add inheritance edges. 1137 for node in inheritance_nodes: 1138 for base in node.class_doc.bases: 1139 if base in nodes: 1140 graph.edges.append(DotGraphEdge(nodes[base], node, 1141 dir='back', arrowtail='empty', 1142 headport='body', tailport='body', 1143 color=INH_LINK_COLOR, weight=100, 1144 style='bold')) 1145 1146 # And we're done! 1147 return graph
    1148 1149 ######################################################################
    1150 -def import_graph(modules, docindex, linker, context=None, **options):
    1151 graph = DotGraph('Import Graph', body='ranksep=.3\n;nodesep=.3\n') 1152 1153 # Options 1154 if options.get('dir', 'RL') != 'TB': # default: right-to-left. 1155 graph.body += 'rankdir=%s\n' % options.get('dir', 'RL') 1156 1157 # Add a node for each module. 1158 nodes = add_valdoc_nodes(graph, modules, linker, context) 1159 1160 # Edges. 1161 edges = set() 1162 for dst in modules: 1163 if dst.imports in (None, UNKNOWN): continue 1164 for var_name in dst.imports: 1165 for i in range(len(var_name), 0, -1): 1166 val_doc = docindex.find(var_name[:i], context) 1167 if isinstance(val_doc, ModuleDoc): 1168 if val_doc in nodes and dst in nodes: 1169 edges.add((nodes[val_doc], nodes[dst])) 1170 break 1171 graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] 1172 1173 return graph
    1174 1175 ######################################################################
    1176 -def call_graph(api_docs, docindex, linker, context=None, **options):
    1177 """ 1178 :param options: 1179 - ``dir``: rankdir for the graph. (default=LR) 1180 - ``add_callers``: also include callers for any of the 1181 routines in ``api_docs``. (default=False) 1182 - ``add_callees``: also include callees for any of the 1183 routines in ``api_docs``. (default=False) 1184 :todo: Add an ``exclude`` option? 1185 """ 1186 if docindex.callers is None: 1187 log.warning("No profiling information for call graph!") 1188 return DotGraph('Call Graph') # return None instead? 1189 1190 if isinstance(context, VariableDoc): 1191 context = context.value 1192 1193 # Get the set of requested functions. 1194 functions = [] 1195 for api_doc in api_docs: 1196 # If it's a variable, get its value. 1197 if isinstance(api_doc, VariableDoc): 1198 api_doc = api_doc.value 1199 # Add the value to the functions list. 1200 if isinstance(api_doc, RoutineDoc): 1201 functions.append(api_doc) 1202 elif isinstance(api_doc, NamespaceDoc): 1203 for vardoc in api_doc.variables.values(): 1204 if isinstance(vardoc.value, RoutineDoc): 1205 functions.append(vardoc.value) 1206 1207 # Filter out functions with no callers/callees? 1208 # [xx] this isnt' quite right, esp if add_callers or add_callees 1209 # options are fales. 1210 functions = [f for f in functions if 1211 (f in docindex.callers) or (f in docindex.callees)] 1212 1213 # Add any callers/callees of the selected functions 1214 func_set = set(functions) 1215 if options.get('add_callers', False) or options.get('add_callees', False): 1216 for func_doc in functions: 1217 if options.get('add_callers', False): 1218 func_set.update(docindex.callers.get(func_doc, ())) 1219 if options.get('add_callees', False): 1220 func_set.update(docindex.callees.get(func_doc, ())) 1221 1222 graph = DotGraph('Call Graph for %s' % name_list(api_docs, context), 1223 node_defaults={'shape':'box', 'width': 0, 'height': 0}) 1224 1225 # Options 1226 if options.get('dir', 'LR') != 'TB': # default: left-to-right 1227 graph.body += 'rankdir=%s\n' % options.get('dir', 'LR') 1228 1229 nodes = add_valdoc_nodes(graph, func_set, linker, context) 1230 1231 # Find the edges. 1232 edges = set() 1233 for func_doc in functions: 1234 for caller in docindex.callers.get(func_doc, ()): 1235 if caller in nodes: 1236 edges.add( (nodes[caller], nodes[func_doc]) ) 1237 for callee in docindex.callees.get(func_doc, ()): 1238 if callee in nodes: 1239 edges.add( (nodes[func_doc], nodes[callee]) ) 1240 graph.edges = [DotGraphEdge(src,dst) for (src,dst) in edges] 1241 1242 return graph
    1243 1244 ###################################################################### 1245 #{ Dot Version 1246 ###################################################################### 1247 1248 _dot_version = None 1249 _DOT_VERSION_RE = re.compile(r'dot version ([\d\.]+)')
    1250 -def get_dot_version():
    1251 global _dot_version 1252 if _dot_version is None: 1253 try: 1254 out, err = run_subprocess([DOT_COMMAND, '-V']) 1255 version_info = err or out 1256 m = _DOT_VERSION_RE.match(version_info) 1257 if m: 1258 _dot_version = [int(x) for x in m.group(1).split('.')] 1259 else: 1260 _dot_version = (0,) 1261 except OSError, e: 1262 _dot_version = (0,) 1263 log.info('Detected dot version %s' % _dot_version) 1264 return _dot_version
    1265 1266 ###################################################################### 1267 #{ Helper Functions 1268 ###################################################################### 1269
    1270 -def add_valdoc_nodes(graph, val_docs, linker, context):
    1271 """ 1272 :todo: Use different node styles for different subclasses of APIDoc 1273 """ 1274 nodes = {} 1275 val_docs = sorted(val_docs, key=lambda d:d.canonical_name) 1276 for i, val_doc in enumerate(val_docs): 1277 label = val_doc.canonical_name.contextualize(context.canonical_name) 1278 node = nodes[val_doc] = DotGraphNode(label) 1279 graph.nodes.append(node) 1280 specialize_valdoc_node(node, val_doc, context, linker.url_for(val_doc)) 1281 return nodes
    1282 1283 NOOP_URL = 'javascript:void(0);' 1284 MODULE_NODE_HTML = ''' 1285 <TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0" 1286 CELLPADDING="0" PORT="table" ALIGN="LEFT"> 1287 <TR><TD ALIGN="LEFT" VALIGN="BOTTOM" HEIGHT="8" WIDTH="16" FIXEDSIZE="true" 1288 BGCOLOR="%s" BORDER="1" PORT="tab"></TD></TR> 1289 <TR><TD ALIGN="LEFT" VALIGN="TOP" BGCOLOR="%s" BORDER="1" 1290 PORT="body" HREF="%s" TOOLTIP="%s">%s</TD></TR> 1291 </TABLE>'''.strip() 1292
    1293 -def specialize_valdoc_node(node, val_doc, context, url):
    1294 """ 1295 Update the style attributes of `node` to reflext its type 1296 and context. 1297 """ 1298 # We can only use html-style nodes if dot_version>2. 1299 dot_version = get_dot_version() 1300 1301 # If val_doc or context is a variable, get its value. 1302 if isinstance(val_doc, VariableDoc) and val_doc.value is not UNKNOWN: 1303 val_doc = val_doc.value 1304 if isinstance(context, VariableDoc) and context.value is not UNKNOWN: 1305 context = context.value 1306 1307 # Set the URL. (Do this even if it points to the page we're 1308 # currently on; otherwise, the tooltip is ignored.) 1309 node['href'] = url or NOOP_URL 1310 1311 if isinstance(val_doc, ModuleDoc) and dot_version >= [2]: 1312 node['shape'] = 'plaintext' 1313 if val_doc == context: color = SELECTED_BG 1314 else: color = MODULE_BG 1315 node['tooltip'] = node['label'] 1316 node['html_label'] = MODULE_NODE_HTML % (color, color, url, 1317 val_doc.canonical_name, 1318 node['label']) 1319 node['width'] = node['height'] = 0 1320 node.port = 'body' 1321 1322 elif isinstance(val_doc, RoutineDoc): 1323 node['shape'] = 'box' 1324 node['style'] = 'rounded' 1325 node['width'] = 0 1326 node['height'] = 0 1327 node['label'] = '%s()' % node['label'] 1328 node['tooltip'] = node['label'] 1329 if val_doc == context: 1330 node['fillcolor'] = SELECTED_BG 1331 node['style'] = 'filled,rounded,bold' 1332 1333 else: 1334 node['shape'] = 'box' 1335 node['width'] = 0 1336 node['height'] = 0 1337 node['tooltip'] = node['label'] 1338 if val_doc == context: 1339 node['fillcolor'] = SELECTED_BG 1340 node['style'] = 'filled,bold'
    1341
    1342 -def name_list(api_docs, context=None):
    1343 if context is not None: 1344 context = context.canonical_name 1345 names = [str(d.canonical_name.contextualize(context)) for d in api_docs] 1346 if len(names) == 0: return '' 1347 if len(names) == 1: return '%s' % names[0] 1348 elif len(names) == 2: return '%s and %s' % (names[0], names[1]) 1349 else: 1350 return '%s, and %s' % (', '.join(names[:-1]), names[-1])
    1351
    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._SummaryExtractor-class.html0000644000175000017500000005247010750103050031412 0ustar pronovicpronovic epydoc.markup.restructuredtext._SummaryExtractor
    Package epydoc :: Package markup :: Module restructuredtext :: Class _SummaryExtractor
    [hide private]
    [frames] | no frames]

    Class _SummaryExtractor

    source code


    A docutils node visitor that extracts the first sentence from the first paragraph in a document.

    Instance Methods [hide private]
     
    __init__(self, document) source code
    call graph 
     
    visit_document(self, node) source code
    call graph 
     
    visit_paragraph(self, node) source code
    call graph 
     
    visit_field(self, node) source code
     
    unknown_visit(self, node)
    Ignore all unknown nodes
    source code
    call graph 

    Inherited from docutils.nodes.NodeVisitor: dispatch_departure, dispatch_visit, unknown_departure

    Class Variables [hide private]
      _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)')

    Inherited from docutils.nodes.NodeVisitor: optional

    Method Details [hide private]

    __init__(self, document)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.nodes.NodeVisitor.__init__

    unknown_visit(self, node)

    source code 
    call graph 

    Ignore all unknown nodes

    Overrides: docutils.nodes.NodeVisitor.unknown_visit

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docstringparser-module.html0000644000175000017500000001563410750103050025142 0ustar pronovicpronovic docstringparser

    Module docstringparser


    Classes

    DocstringField

    Functions

    add_metadata_from_var
    check_type_fields
    get_docformat
    initialize_api_doc
    parse_docstring
    parse_function_signature
    process_arg_field
    process_cvar_field
    process_deffield_field
    process_field
    process_group_field
    process_include_field
    process_ivar_field
    process_kwarg_field
    process_raise_field
    process_return_field
    process_rtype_field
    process_sort_field
    process_summary_field
    process_type_field
    process_undocumented_field
    process_var_field
    register_field_handler
    report_errors
    set_var_descr
    set_var_type
    split_init_fields
    unindent_docstring
    user_docfields

    Variables

    BAD_CONTEXT
    BAD_PARAM
    DEFAULT_DOCFORMAT
    EXCEPTION_TAGS
    EXPECTED_ARG
    EXPECTED_SINGLE_ARG
    PARAMETER_TAGS
    REDEFINED
    RETURN_PDS
    STANDARD_FIELDS
    UNEXPECTED_ARG
    UNKNOWN_TAG
    VARIABLE_TAGS

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.cli.UnifiedProgressConsoleLogger-class.html0000644000175000017500000005016610750103050027326 0ustar pronovicpronovic epydoc.cli.UnifiedProgressConsoleLogger
    Package epydoc :: Module cli :: Class UnifiedProgressConsoleLogger
    [hide private]
    [frames] | no frames]

    Class UnifiedProgressConsoleLogger

    source code


    Instance Methods [hide private]
     
    __init__(self, verbosity, stages, progress_mode=None) source code
     
    progress(self, percent, message='')
    Update the progress display.
    source code
     
    start_progress(self, header=None)
    Begin displaying progress for a new task.
    source code
     
    end_progress(self)
    Finish off the display of progress for the current task.
    source code
     
    print_times(self) source code

    Inherited from ConsoleLogger: end_block, log, start_block

    Inherited from ConsoleLogger (private): _format, _report, _timestr

    Inherited from log.Logger: close

    Instance Variables [hide private]

    Inherited from ConsoleLogger: reported_message_levels, suppressed_docstring_warning

    Method Details [hide private]

    __init__(self, verbosity, stages, progress_mode=None)
    (Constructor)

    source code 
    Overrides: ConsoleLogger.__init__

    progress(self, percent, message='')

    source code 

    Update the progress display.

    Parameters:
    • percent - A float from 0.0 to 1.0, indicating how much progress has been made.
    • message - A message indicating the most recent action that contributed towards that progress.
    Overrides: log.Logger.progress
    (inherited documentation)

    start_progress(self, header=None)

    source code 

    Begin displaying progress for a new task. header is a description of the task for which progress is being reported. Each call to start_progress must be followed by a call to end_progress (with no intervening calls to start_progress).

    Overrides: log.Logger.start_progress
    (inherited documentation)

    end_progress(self)

    source code 

    Finish off the display of progress for the current task. See start_progress for more information.

    Overrides: log.Logger.end_progress
    (inherited documentation)

    print_times(self)

    source code 
    Overrides: ConsoleLogger.print_times

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup-module.html0000644000175000017500000007602010750103050022441 0ustar pronovicpronovic epydoc.markup
    Package epydoc :: Package markup
    [hide private]
    [frames] | no frames]

    Package markup

    source code

    Markup language support for docstrings. Each submodule defines a parser for a single markup language. These parsers convert an object's docstring to a ParsedDocstring, a standard intermediate representation that can be used to generate output. ParsedDocstrings support the following operations:

    The parse() function provides a single interface to the epydoc.markup package: it takes a docstring and the name of a markup language; delegates to the appropriate parser; and returns the parsed docstring (along with any errors or warnings that were generated).

    The ParsedDocstring output generation methods (to_format()) use a DocstringLinker to link the docstring output with the rest of the documentation that epydoc generates. DocstringLinkers are currently responsible for translating two kinds of crossreference:

    A parsed docstring's fields can be extracted using the ParsedDocstring.split_fields() method. This method divides a docstring into its main body and a list of Fields, each of which encodes a single field. The field's bodies are encoded as ParsedDocstrings.

    Markup errors are represented using ParseErrors. These exception classes record information about the cause, location, and severity of each error.

    Submodules [hide private]

    Classes [hide private]
      ParsedDocstring
    A standard intermediate representation for parsed docstrings that can be used to generate output.
      Field
    The contents of a docstring's field.
      DocstringLinker
    A translator for crossreference links into and out of a ParsedDocstring.
      ConcatenatedDocstring
        Errors and Warnings
      ParseError
    The base class for errors generated while parsing docstrings.
    Functions [hide private]
    ParsedDocstring
    parse(docstring, markup='plaintext', errors=None, **options)
    Parse the given docstring, and use it to construct a ParsedDocstring.
    source code
    call graph 
     
    register_markup_language(name, parse_function)
    Register a new markup language named name, which can be parsed by the function parse_function.
    source code
     
    _parse_warn(estr)
    Print a warning message.
    source code
        Utility Functions
    ParsedDocstring
    parse_type_of(obj)
    Returns: A ParsedDocstring that encodes the type of the given object.
    source code
    Variables [hide private]
      _markup_language_registry = {'restructuredtext': 'epydoc.marku...
      MARKUP_LANGUAGES_USED = set(['epytext', 'plaintext', u'restruc...
      _parse_warnings = {}
    Used by _parse_warn.
    int SCRWIDTH
    The default width with which text will be wrapped when formatting the output of the parser.
    Function Details [hide private]

    parse(docstring, markup='plaintext', errors=None, **options)

    source code 
    call graph 

    Parse the given docstring, and use it to construct a ParsedDocstring. If any fatal ParseErrors are encountered while parsing the docstring, then the docstring will be rendered as plaintext, instead.

    Parameters:
    • docstring (string) - The docstring to encode.
    • markup (string) - The name of the markup language that is used by the docstring. If the markup language is not supported, then the docstring will be treated as plaintext. The markup name is case-insensitive.
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored. If no list is specified, then fatal errors will generate exceptions, and non-fatal errors will be ignored.
    Returns: ParsedDocstring
    A ParsedDocstring that encodes the contents of docstring.
    Raises:
    • ParseError - If errors is None and an error is encountered while parsing.

    register_markup_language(name, parse_function)

    source code 

    Register a new markup language named name, which can be parsed by the function parse_function.

    Parameters:
    • name - The name of the markup language. name should be a simple identifier, such as 'epytext' or 'restructuredtext'. Markup language names are case insensitive.
    • parse_function - A function which can be used to parse the markup language, and returns a ParsedDocstring. It should have the following signature:
      >>> def parse(s, errors):
      ...     'returns a ParsedDocstring'

      Where:

      • s is the string to parse. (s will be a unicode string.)
      • errors is a list; any errors that are generated during docstring parsing should be appended to this list (as ParseError objects).

    _parse_warn(estr)

    source code 

    Print a warning message. If the given error has already been printed, then do nothing.

    parse_type_of(obj)

    source code 
    Parameters:
    • obj (any) - The object whose type should be returned as DOM document.
    Returns: ParsedDocstring
    A ParsedDocstring that encodes the type of the given object.

    Variables Details [hide private]

    _markup_language_registry

    Value:
    {'restructuredtext': 'epydoc.markup.restructuredtext', 'epytext': 'epy\
    doc.markup.epytext', 'plaintext': 'epydoc.markup.plaintext', 'javadoc'\
    : 'epydoc.markup.javadoc',}
    

    MARKUP_LANGUAGES_USED

    Value:
    set(['epytext', 'plaintext', u'restructuredtext'])
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc-module.html0000644000175000017500000007574610750103050022417 0ustar pronovicpronovic epydoc.apidoc
    Package epydoc :: Module apidoc
    [hide private]
    [frames] | no frames]

    Module apidoc

    source code

    Classes for encoding API documentation about Python programs. These classes are used as a common representation for combining information derived from introspection and from parsing.

    The API documentation for a Python program is encoded using a graph of APIDoc objects, each of which encodes information about a single Python variable or value. APIDoc has two direct subclasses: VariableDoc, for documenting variables; and ValueDoc, for documenting values. The ValueDoc class is subclassed further, to define the different pieces of information that should be recorded about each value type:

    Class Hierarchy for APIDoc
    Class Hierarchy for APIDoc

    The distinction between variables and values is intentionally made explicit. This allows us to distinguish information about a variable itself (such as whether it should be considered 'public' in its containing namespace) from information about the value it contains (such as what type the value has). This distinction is also important because several variables can contain the same value: each variable should be described by a separate VariableDoc; but we only need one ValueDoc, since they share a single value.


    To Do: Add a cache to canonical name lookup?

    Classes [hide private]
      DottedName
    A sequence of identifiers, separated by periods, used to name a Python variable, value, or argument.
      _Sentinel
    A unique value that won't compare equal to any other value.
      APIDoc
    API documentation information for a single element of a Python program.
      VariableDoc
    API documentation information about a single Python variable.
      ValueDoc
    API documentation information about a single Python value.
      GenericValueDoc
    API documentation about a 'generic' value, i.e., one that does not have its own docstring or any information other than its value and parse representation.
      NamespaceDoc
    API documentation information about a singe Python namespace value.
      ModuleDoc
    API documentation information about a single module.
      ClassDoc
    API documentation information about a single class.
      RoutineDoc
    API documentation information about a single routine.
      ClassMethodDoc
      StaticMethodDoc
      PropertyDoc
    API documentation information about a single property.
      DocIndex
    [xx] out of date.
    Functions [hide private]
     
    reachable_valdocs(root, **filters)
    Return a list of all ValueDocs that can be reached, directly or indirectly from the given root list of ValueDocs.
    source code
    call graph 
     
    _flatten(lst, out=None)
    Return a flattened version of lst.
    source code
    call graph 
     
    pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(), backpointers=None)
    Returns: A multiline pretty-printed string representation for the given APIDoc.
    source code
     
    _pp_list(api_doc, items, doublespace, depth, exclude, include, backpointers, is_last) source code
     
    _pp_dict(api_doc, dict, doublespace, depth, exclude, include, backpointers, is_last) source code
     
    _pp_apidoc(api_doc, val, doublespace, depth, exclude, include, backpointers, is_last) source code
     
    _pp_val(api_doc, val, doublespace, depth, exclude, include, backpointers) source code
    Variables [hide private]
      UNKNOWN = _Sentinel('UNKNOWN')
    A special value used to indicate that a given piece of information about an object is unknown.
    Function Details [hide private]

    reachable_valdocs(root, **filters)

    source code 
    call graph 

    Return a list of all ValueDocs that can be reached, directly or indirectly from the given root list of ValueDocs.

    Parameters:
    • filters - A set of filters that can be used to prevent reachable_valdocs from following specific link types when looking for ValueDocs that can be reached from the root set. See APIDoc.apidoc_links for a more complete description.

    pp_apidoc(api_doc, doublespace=0, depth=5, exclude=(), include=(), backpointers=None)

    source code 
    Parameters:
    • doublespace - If true, then extra lines will be inserted to make the output more readable.
    • depth - The maximum depth that pp_apidoc will descend into descendent VarDocs. To put no limit on depth, use depth=-1.
    • exclude - A list of names of attributes whose values should not be shown.
    • backpointers - For internal use.
    Returns:
    A multiline pretty-printed string representation for the given APIDoc.

    Variables Details [hide private]

    UNKNOWN

    A special value used to indicate that a given piece of information about an object is unknown. This is used as the default value for all instance variables.

    Value:
    _Sentinel('UNKNOWN')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.plaintext.PlaintextWriter-class.html0000644000175000017500000004405110750103050030136 0ustar pronovicpronovic epydoc.docwriter.plaintext.PlaintextWriter
    Package epydoc :: Package docwriter :: Module plaintext :: Class PlaintextWriter
    [hide private]
    [frames] | no frames]

    Class PlaintextWriter

    source code

    Instance Methods [hide private]
     
    write(self, api_doc, **options) source code
     
    write_module(self, out, mod_doc) source code
     
    baselist(self, class_doc) source code
     
    write_class(self, out, class_doc, name=None, prefix='', verbose=True) source code
     
    write_variable(self, out, var_doc, name=None, prefix='', verbose=True) source code
     
    write_property(self, out, prop_doc, name=None, prefix='', verbose=True) source code
     
    write_function(self, out, func_doc, name=None, prefix='', verbose=True) source code
     
    write_signature(self, out, func_doc, name, prefix) source code
     
    fmt_arg(self, name, default) source code
     
    write_list(self, out, heading, doc, value_type=None, imported=False, inherited=False, prefix='', noindent=False, verbose=True) source code
     
    _descr(self, descr, prefix) source code
     
    bold(self, text)
    Write a string in bold by overstriking.
    source code
     
    title(self, text, indent) source code
     
    section(self, text, indent='') source code
    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.RoutineDoc-class.html0000644000175000017500000013371410750103050024277 0ustar pronovicpronovic epydoc.apidoc.RoutineDoc
    Package epydoc :: Module apidoc :: Class RoutineDoc
    [hide private]
    [frames] | no frames]

    Class RoutineDoc

    source code


    API documentation information about a single routine.

    Instance Methods [hide private]
    bool
    is_detailed(self)
    Does this object deserve a box with extra details?
    source code
    call graph 
     
    all_args(self)
    Returns: A list of the names of all arguments (positional, vararg, and keyword), in order.
    source code
    call graph 

    Inherited from ValueDoc: __getstate__, __repr__, __setstate__, apidoc_links

    Inherited from APIDoc: __cmp__, __hash__, __init__, __setattr__, __str__, merge_and_overwrite, pp, specialize_to

    Inherited from APIDoc (private): _debug_setattr

    Inherited from object: __delattr__, __getattribute__, __new__, __reduce__, __reduce_ex__

        Value Representation

    Inherited from ValueDoc: pyval_repr, summary_pyval_repr

    Class Variables [hide private]
        Value Representation

    Inherited from ValueDoc: REPR_LINELEN, REPR_MAXLINES, REPR_MIN_SCORE, SUMMARY_REPR_LINELEN

    Instance Variables [hide private]
    str callgraph_uid = None
    DotGraph.uid of the call graph for the function.

    Inherited from ValueDoc: canonical_name, toktree

        Signature
    list posargs = _Sentinel('UNKNOWN')
    The names of the routine's positional arguments.
    list of ValueDoc or None posarg_defaults = _Sentinel('UNKNOWN')
    API documentation for the positional arguments' default values.
    string or None vararg = _Sentinel('UNKNOWN')
    The name of the routine's vararg argument, or None if it has no vararg argument.
    string or None kwarg = _Sentinel('UNKNOWN')
    The name of the routine's keyword argument, or None if it has no keyword argument.
    int lineno = _Sentinel('UNKNOWN')
    The line number of the first line of the function's signature.
        Decorators
    list of string decorators = _Sentinel('UNKNOWN')
    A list of names of decorators that were applied to this routine, in the order that they are listed in the source code.
        Information Extracted from Docstrings
    list arg_descrs = _Sentinel('UNKNOWN')
    A list of descriptions of the routine's arguments.
    dict from string to ParsedDocstring arg_types = _Sentinel('UNKNOWN')
    Descriptions of the expected types for the routine's arguments, encoded as a dictionary mapping from argument names to type descriptions.
    ParsedDocstring return_descr = _Sentinel('UNKNOWN')
    A description of the value returned by this routine.
    ParsedDocstring return_type = _Sentinel('UNKNOWN')
    A description of expected type for the value returned by this routine.
    list exception_descrs = _Sentinel('UNKNOWN')
    A list of descriptions of exceptions that the routine might raise.

    Inherited from APIDoc: descr, extra_docstring_fields, metadata, other_docs, summary

        Value Representation

    Inherited from ValueDoc: parse_repr, pyval

        Context

    Inherited from ValueDoc: defining_module

        Information about Imported Variables

    Inherited from ValueDoc: proxy_for

        Docstrings

    Inherited from APIDoc: docstring, docstring_lineno

        Source Information

    Inherited from APIDoc: docs_extracted_by

    Properties [hide private]

    Inherited from object: __class__

    Method Details [hide private]

    is_detailed(self)

    source code 
    call graph 

    Does this object deserve a box with extra details?

    Returns: bool
    True if the object needs extra details, else False.
    Overrides: APIDoc.is_detailed
    (inherited documentation)

    all_args(self)

    source code 
    call graph 
    Returns:
    A list of the names of all arguments (positional, vararg, and keyword), in order. If a positional argument consists of a tuple of names, then that tuple will be flattened.

    Instance Variable Details [hide private]

    posargs

    The names of the routine's positional arguments. If an argument list contains "unpacking" arguments, then their names will be specified using nested lists. E.g., if a function's argument list is ((x1,y1), (x2,y2)), then posargs will be [['x1','y1'], ['x2','y2']].
    Type:
    list
    Value:
    _Sentinel('UNKNOWN')
    

    posarg_defaults

    API documentation for the positional arguments' default values. This list has the same length as posargs, and each element of posarg_defaults describes the corresponding argument in posargs. For positional arguments with no default, posargs_defaults will contain None.
    Type:
    list of ValueDoc or None
    Value:
    _Sentinel('UNKNOWN')
    

    lineno

    The line number of the first line of the function's signature. For Python functions, this is equal to func.func_code.co_firstlineno. The first line of a file is considered line 1.
    Type:
    int
    Value:
    _Sentinel('UNKNOWN')
    

    decorators

    A list of names of decorators that were applied to this routine, in the order that they are listed in the source code. (I.e., in the reverse of the order that they were applied in.)
    Type:
    list of string
    Value:
    _Sentinel('UNKNOWN')
    

    arg_descrs

    A list of descriptions of the routine's arguments. Each element of this list is a tuple (args, descr), where args is a list of argument names; and descr is a ParsedDocstring describing the argument(s) specified by arg.
    Type:
    list
    Value:
    _Sentinel('UNKNOWN')
    

    exception_descrs

    A list of descriptions of exceptions that the routine might raise. Each element of this list is a tuple (exc, descr), where exc is a string contianing the exception name; and descr is a ParsedDocstring describing the circumstances under which the exception specified by exc is raised.
    Type:
    list
    Value:
    _Sentinel('UNKNOWN')
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink.UrlGenerator-class.html0000644000175000017500000003571610750103050026527 0ustar pronovicpronovic epydoc.docwriter.xlink.UrlGenerator
    Package epydoc :: Package docwriter :: Module xlink :: Class UrlGenerator
    [hide private]
    [frames] | no frames]

    Class UrlGenerator

    source code


    Generate URL from an object name.
    Nested Classes [hide private]
      IndexAmbiguous
    The name looked for is ambiguous
    Instance Methods [hide private]
    str
    get_url(self, name)
    Look for a name and return the matching URL documentation.
    source code
    tuple of str
    get_canonical_name(self, name)
    Convert an object name into a canonical name.
    source code
    Class Variables [hide private]
      _SEP_RE = re.compile(r'(?x)([a-zA-Z0-9_]+)|(\.|::|->)|(.)')
    Method Details [hide private]

    get_url(self, name)

    source code 

    Look for a name and return the matching URL documentation.

    First look for a fully qualified name. If not found, try with partial name.

    If no url exists for the given object, return None.

    Parameters:
    • name (str) - the name to look for
    Returns: str
    the URL that can be used to reach the name documentation. None if no such URL exists.
    Raises:
    • IndexError - no object found with name
    • DocUrlGenerator.IndexAmbiguous - more than one object found with a non-fully qualified name; notice that this is an IndexError subclass

    get_canonical_name(self, name)

    source code 

    Convert an object name into a canonical name.

    the canonical name of an object is a tuple of strings containing its name fragments, splitted on any allowed separator ('.', '::', '->').

    Noise such parenthesis to indicate a function is discarded.

    Parameters:
    • name (str) - an object name, such as os.path.prefix() or lib::foo::bar
    Returns: tuple of str
    the fully qualified name such ('os', 'path', 'prefix') and ('lib', 'foo', 'bar')

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext.ParsedRstDocstring-class.html0000644000175000017500000012466110750103050031510 0ustar pronovicpronovic epydoc.markup.restructuredtext.ParsedRstDocstring
    Package epydoc :: Package markup :: Module restructuredtext :: Class ParsedRstDocstring
    [hide private]
    [frames] | no frames]

    Class ParsedRstDocstring

    source code


    An encoded version of a ReStructuredText docstring. The contents of the docstring are encoded in the _document instance variable.

    Instance Methods [hide private]
     
    __init__(self, document) source code
    call graph 
    (ParsedDocstring, list of Field)
    split_fields(self, errors=None)
    Split this docstring into its body and its fields.
    source code
    call graph 
    (ParsedDocstring, bool)
    summary(self)
    Returns: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary.
    source code
    call graph 
    string
    to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options)
    Translate this docstring to HTML.
    source code
    call graph 
    string
    to_latex(self, docstring_linker, **options)
    Translate this docstring to LaTeX.
    source code
    string
    to_plaintext(self, docstring_linker, **options)
    Translate this docstring to plaintext.
    source code
    call graph 
     
    __repr__(self) source code
    list of ParsedDocstring
    index_terms(self)
    Returns: The list of index terms that are defined in this docstring.
    source code
    call graph 

    Inherited from ParsedDocstring: __add__, concatenate

    Instance Variables [hide private]
    docutils.nodes.document _document
    A ReStructuredText document, encoding the docstring.
    Method Details [hide private]

    __init__(self, document)
    (Constructor)

    source code 
    call graph 
    Parameters:
    • document (docutils.nodes.document)

    split_fields(self, errors=None)

    source code 
    call graph 

    Split this docstring into its body and its fields.

    Parameters:
    • errors - A list where any errors generated during splitting will be stored. If no list is specified, then errors will be ignored.
    Returns: (ParsedDocstring, list of Field)
    A tuple (body, fields), where body is the main body of this docstring, and fields is a list of its fields. If the resulting body is empty, return None for the body.
    Overrides: ParsedDocstring.split_fields
    (inherited documentation)

    summary(self)

    source code 
    call graph 
    Returns: (ParsedDocstring, bool)
    A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring.
    Overrides: ParsedDocstring.summary
    (inherited documentation)

    to_html(self, docstring_linker, directory=None, docindex=None, context=None, **options)

    source code 
    call graph 

    Translate this docstring to HTML.

    Parameters:
    • docstring_linker - An HTML translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    An HTML fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_html
    (inherited documentation)

    to_latex(self, docstring_linker, **options)

    source code 

    Translate this docstring to LaTeX.

    Parameters:
    • docstring_linker - A LaTeX translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A LaTeX fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_latex
    (inherited documentation)

    to_plaintext(self, docstring_linker, **options)

    source code 
    call graph 

    Translate this docstring to plaintext.

    Parameters:
    • docstring_linker - A plaintext translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A plaintext fragment that encodes this docstring.
    Overrides: ParsedDocstring.to_plaintext
    (inherited documentation)

    index_terms(self)

    source code 
    call graph 
    Returns: list of ParsedDocstring
    The list of index terms that are defined in this docstring. Each of these items will be added to the index page of the documentation.
    Overrides: ParsedDocstring.index_terms
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.TokenizationError-class.html0000644000175000017500000002327610750103050027456 0ustar pronovicpronovic epydoc.markup.epytext.TokenizationError
    Package epydoc :: Package markup :: Module epytext :: Class TokenizationError
    [hide private]
    [frames] | no frames]

    Class TokenizationError

    source code


    An error generated while tokenizing a formatted documentation string.

    Instance Methods [hide private]

    Inherited from ParseError: __cmp__, __init__, __repr__, __str__, descr, is_fatal, linenum, set_linenum_offset

    Inherited from exceptions.Exception: __getitem__

    Instance Variables [hide private]

    Inherited from ParseError (private): _descr, _fatal, _linenum, _offset

    epydoc-3.0.1+dfsg/doc/api/epydoc.docstringparser-pysrc.html0000644000175000017500000147147310750103050024242 0ustar pronovicpronovic epydoc.docstringparser
    Package epydoc :: Module docstringparser
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docstringparser

       1  # epydoc -- Docstring processing 
       2  # 
       3  # Copyright (C) 2005 Edward Loper 
       4  # Author: Edward Loper <edloper@loper.org> 
       5  # URL: <http://epydoc.sf.net> 
       6  # 
       7  # $Id: docstringparser.py 1689 2008-01-30 17:01:02Z edloper $ 
       8   
       9  """ 
      10  Parse docstrings and handle any fields it defines, such as C{@type} 
      11  and C{@author}.  Fields are used to describe specific information 
      12  about an object.  There are two classes of fields: X{simple fields} 
      13  and X{special fields}. 
      14   
      15  Simple fields are fields that get stored directly in an C{APIDoc}'s 
      16  metadata dictionary, without any special processing.  The set of 
      17  simple fields is defined by the list L{STANDARD_FIELDS}, whose 
      18  elements are L{DocstringField}s. 
      19   
      20  Special fields are fields that perform some sort of processing on the 
      21  C{APIDoc}, or add information to attributes other than the metadata 
      22  dictionary.  Special fields are are handled by field handler 
      23  functions, which are registered using L{register_field_handler}. 
      24  """ 
      25  __docformat__ = 'epytext en' 
      26   
      27   
      28  ###################################################################### 
      29  ## Imports 
      30  ###################################################################### 
      31   
      32  import re, sys 
      33  from epydoc import markup 
      34  from epydoc.markup import epytext 
      35  from epydoc.apidoc import * 
      36  from epydoc.docintrospecter import introspect_docstring_lineno 
      37  from epydoc.util import py_src_filename 
      38  from epydoc import log 
      39  import epydoc.docparser 
      40  import __builtin__, exceptions 
      41   
      42  ###################################################################### 
      43  # Docstring Fields 
      44  ###################################################################### 
      45   
    
    46 -class DocstringField:
    47 """ 48 A simple docstring field, which can be used to describe specific 49 information about an object, such as its author or its version. 50 Simple docstring fields are fields that take no arguments, and 51 are displayed as simple sections. 52 53 @ivar tags: The set of tags that can be used to identify this 54 field. 55 @ivar singular: The label that should be used to identify this 56 field in the output, if the field contains one value. 57 @ivar plural: The label that should be used to identify this 58 field in the output, if the field contains multiple values. 59 @ivar short: If true, then multiple values should be combined 60 into a single comma-delimited list. If false, then 61 multiple values should be listed separately in a bulleted 62 list. 63 @ivar multivalue: If true, then multiple values may be given 64 for this field; if false, then this field can only take a 65 single value, and a warning should be issued if it is 66 redefined. 67 @ivar takes_arg: If true, then this field expects an argument; 68 and a separate field section will be constructed for each 69 argument value. The label (and plural label) should include 70 a '%s' to mark where the argument's string rep should be 71 added. 72 """
    73 - def __init__(self, tags, label, plural=None, 74 short=0, multivalue=1, takes_arg=0, 75 varnames=None):
    76 if type(tags) in (list, tuple): 77 self.tags = tuple(tags) 78 elif type(tags) is str: 79 self.tags = (tags,) 80 else: raise TypeError('Bad tags: %s' % tags) 81 self.singular = label 82 if plural is None: self.plural = label 83 else: self.plural = plural 84 self.multivalue = multivalue 85 self.short = short 86 self.takes_arg = takes_arg 87 self.varnames = varnames or []
    88
    89 - def __cmp__(self, other):
    90 if not isinstance(other, DocstringField): return -1 91 return cmp(self.tags, other.tags)
    92
    93 - def __hash__(self):
    94 return hash(self.tags)
    95
    96 - def __repr__(self):
    97 return '<Field: %s>' % self.tags[0]
    98 99 STANDARD_FIELDS = [ 100 #: A list of the standard simple fields accepted by epydoc. This 101 #: list can be augmented at run-time by a docstring with the special 102 #: C{@deffield} field. The order in which fields are listed here 103 #: determines the order in which they will be displayed in the 104 #: output. 105 106 # If it's deprecated, put that first. 107 DocstringField(['deprecated', 'depreciated'], 108 'Deprecated', multivalue=0, varnames=['__deprecated__']), 109 110 # Status info 111 DocstringField(['version'], 'Version', multivalue=0, 112 varnames=['__version__']), 113 DocstringField(['date'], 'Date', multivalue=0, 114 varnames=['__date__']), 115 DocstringField(['status'], 'Status', multivalue=0), 116 117 # Bibliographic Info 118 DocstringField(['author', 'authors'], 'Author', 'Authors', short=1, 119 varnames=['__author__', '__authors__']), 120 DocstringField(['contact'], 'Contact', 'Contacts', short=1, 121 varnames=['__contact__']), 122 DocstringField(['organization', 'org'], 123 'Organization', 'Organizations'), 124 DocstringField(['copyright', '(c)'], 'Copyright', multivalue=0, 125 varnames=['__copyright__']), 126 DocstringField(['license'], 'License', multivalue=0, 127 varnames=['__license__']), 128 129 # Various warnings etc. 130 DocstringField(['bug'], 'Bug', 'Bugs'), 131 DocstringField(['warning', 'warn'], 'Warning', 'Warnings'), 132 DocstringField(['attention'], 'Attention'), 133 DocstringField(['note'], 'Note', 'Notes'), 134 135 # Formal conditions 136 DocstringField(['requires', 'require', 'requirement'], 'Requires'), 137 DocstringField(['precondition', 'precond'], 138 'Precondition', 'Preconditions'), 139 DocstringField(['postcondition', 'postcond'], 140 'Postcondition', 'Postconditions'), 141 DocstringField(['invariant'], 'Invariant'), 142 143 # When was it introduced (version # or date) 144 DocstringField(['since'], 'Since', multivalue=0), 145 146 # Changes made 147 DocstringField(['change', 'changed'], 'Change Log'), 148 149 # Crossreferences 150 DocstringField(['see', 'seealso'], 'See Also', short=1), 151 152 # Future Work 153 DocstringField(['todo'], 'To Do', takes_arg=True), 154 155 # Permissions (used by zope-based projects) 156 DocstringField(['permission', 'permissions'], 'Permission', 'Permissions') 157 ] 158 159 ###################################################################### 160 #{ Docstring Parsing 161 ###################################################################### 162 163 DEFAULT_DOCFORMAT = 'epytext' 164 """The name of the default markup languge used to process docstrings.""" 165 166 # [xx] keep track of which ones we've already done, in case we're 167 # asked to process one twice? e.g., for @include we might have to 168 # parse the included docstring earlier than we might otherwise..?? 169
    170 -def parse_docstring(api_doc, docindex, suppress_warnings=[]):
    171 """ 172 Process the given C{APIDoc}'s docstring. In particular, populate 173 the C{APIDoc}'s C{descr} and C{summary} attributes, and add any 174 information provided by fields in the docstring. 175 176 @param docindex: A DocIndex, used to find the containing 177 module (to look up the docformat); and to find any 178 user docfields defined by containing objects. 179 @param suppress_warnings: A set of objects for which docstring 180 warnings should be suppressed. 181 """ 182 if api_doc.metadata is not UNKNOWN: 183 if not (isinstance(api_doc, RoutineDoc) 184 and api_doc.canonical_name[-1] == '__init__'): 185 log.debug("%s's docstring processed twice" % 186 api_doc.canonical_name) 187 return 188 189 initialize_api_doc(api_doc) 190 191 # If there's no docstring, then check for special variables (e.g., 192 # __version__), and then return -- there's nothing else to do. 193 if (api_doc.docstring in (None, UNKNOWN)): 194 if isinstance(api_doc, NamespaceDoc): 195 for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): 196 add_metadata_from_var(api_doc, field) 197 return 198 199 # Remove leading indentation from the docstring. 200 api_doc.docstring = unindent_docstring(api_doc.docstring) 201 202 # Decide which docformat is used by this module. 203 docformat = get_docformat(api_doc, docindex) 204 205 # A list of markup errors from parsing. 206 parse_errors = [] 207 208 # Extract a signature from the docstring, if it has one. This 209 # overrides any signature we got via introspection/parsing. 210 if isinstance(api_doc, RoutineDoc): 211 parse_function_signature(api_doc, None, docformat, parse_errors) 212 213 # Parse the docstring. Any errors encountered are stored as 214 # `ParseError` objects in the errors list. 215 parsed_docstring = markup.parse(api_doc.docstring, docformat, 216 parse_errors) 217 218 # Divide the docstring into a description and a list of 219 # fields. 220 descr, fields = parsed_docstring.split_fields(parse_errors) 221 api_doc.descr = descr 222 223 field_warnings = [] 224 225 # Handle the constructor fields that have been defined in the class 226 # docstring. This code assumes that a class docstring is parsed before 227 # the same class __init__ docstring. 228 if isinstance(api_doc, ClassDoc): 229 230 # Parse ahead the __init__ docstring for this class 231 initvar = api_doc.variables.get('__init__') 232 if initvar and isinstance(initvar.value, RoutineDoc): 233 init_api_doc = initvar.value 234 parse_docstring(init_api_doc, docindex, suppress_warnings) 235 236 parse_function_signature(init_api_doc, api_doc, 237 docformat, parse_errors) 238 init_fields = split_init_fields(fields, field_warnings) 239 240 # Process fields 241 for field in init_fields: 242 try: 243 process_field(init_api_doc, docindex, field.tag(), 244 field.arg(), field.body()) 245 except ValueError, e: field_warnings.append(str(e)) 246 247 # Process fields 248 for field in fields: 249 try: 250 process_field(api_doc, docindex, field.tag(), 251 field.arg(), field.body()) 252 except ValueError, e: field_warnings.append(str(e)) 253 254 # Check to make sure that all type parameters correspond to 255 # some documented parameter. 256 check_type_fields(api_doc, field_warnings) 257 258 # Check for special variables (e.g., __version__) 259 if isinstance(api_doc, NamespaceDoc): 260 for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): 261 add_metadata_from_var(api_doc, field) 262 263 # Extract a summary 264 if api_doc.summary is None and api_doc.descr is not None: 265 api_doc.summary, api_doc.other_docs = api_doc.descr.summary() 266 267 # If the summary is empty, but the return field is not, then use 268 # the return field to generate a summary description. 269 if (isinstance(api_doc, RoutineDoc) and api_doc.summary is None and 270 api_doc.return_descr is not None): 271 s, o = api_doc.return_descr.summary() 272 api_doc.summary = RETURN_PDS + s 273 api_doc.other_docs = o 274 275 # [XX] Make sure we don't have types/param descrs for unknown 276 # vars/params? 277 278 # Report any errors that occured 279 if api_doc in suppress_warnings: 280 if parse_errors or field_warnings: 281 log.info("Suppressing docstring warnings for %s, since it " 282 "is not included in the documented set." % 283 api_doc.canonical_name) 284 else: 285 report_errors(api_doc, docindex, parse_errors, field_warnings)
    286
    287 -def add_metadata_from_var(api_doc, field):
    288 for varname in field.varnames: 289 # Check if api_doc has a variable w/ the given name. 290 if varname not in api_doc.variables: continue 291 292 # Check moved here from before the for loop because we expect to 293 # reach rarely this point. The loop below is to be performed more than 294 # once only for fields with more than one varname, which currently is 295 # only 'author'. 296 for md in api_doc.metadata: 297 if field == md[0]: 298 return # We already have a value for this metadata. 299 300 var_doc = api_doc.variables[varname] 301 if var_doc.value is UNKNOWN: continue 302 val_doc = var_doc.value 303 value = [] 304 305 # Try extracting the value from the pyval. 306 ok_types = (basestring, int, float, bool, type(None)) 307 if val_doc.pyval is not UNKNOWN: 308 if isinstance(val_doc.pyval, ok_types): 309 value = [val_doc.pyval] 310 elif field.multivalue: 311 if isinstance(val_doc.pyval, (tuple, list)): 312 for elt in val_doc.pyval: 313 if not isinstance(elt, ok_types): break 314 else: 315 value = list(val_doc.pyval) 316 317 # Try extracting the value from the parse tree. 318 elif val_doc.toktree is not UNKNOWN: 319 try: value = [epydoc.docparser.parse_string(val_doc.toktree)] 320 except KeyboardInterrupt: raise 321 except: pass 322 if field.multivalue and not value: 323 try: value = epydoc.docparser.parse_string_list(val_doc.toktree) 324 except KeyboardInterrupt: raise 325 except: raise 326 327 # Add any values that we found. 328 for elt in value: 329 if isinstance(elt, str): 330 elt = decode_with_backslashreplace(elt) 331 else: 332 elt = unicode(elt) 333 elt = epytext.ParsedEpytextDocstring( 334 epytext.parse_as_para(elt), inline=True) 335 336 # Add in the metadata and remove from the variables 337 api_doc.metadata.append( (field, varname, elt) ) 338 339 # Remove the variable itself (unless it's documented) 340 if var_doc.docstring in (None, UNKNOWN): 341 del api_doc.variables[varname] 342 if api_doc.sort_spec is not UNKNOWN: 343 try: api_doc.sort_spec.remove(varname) 344 except ValueError: pass
    345
    346 -def initialize_api_doc(api_doc):
    347 """A helper function for L{parse_docstring()} that initializes 348 the attributes that C{parse_docstring()} will write to.""" 349 if api_doc.descr is UNKNOWN: 350 api_doc.descr = None 351 if api_doc.summary is UNKNOWN: 352 api_doc.summary = None 353 if api_doc.metadata is UNKNOWN: 354 api_doc.metadata = [] 355 if isinstance(api_doc, RoutineDoc): 356 if api_doc.arg_descrs is UNKNOWN: 357 api_doc.arg_descrs = [] 358 if api_doc.arg_types is UNKNOWN: 359 api_doc.arg_types = {} 360 if api_doc.return_descr is UNKNOWN: 361 api_doc.return_descr = None 362 if api_doc.return_type is UNKNOWN: 363 api_doc.return_type = None 364 if api_doc.exception_descrs is UNKNOWN: 365 api_doc.exception_descrs = [] 366 if isinstance(api_doc, (VariableDoc, PropertyDoc)): 367 if api_doc.type_descr is UNKNOWN: 368 api_doc.type_descr = None 369 if isinstance(api_doc, NamespaceDoc): 370 if api_doc.group_specs is UNKNOWN: 371 api_doc.group_specs = [] 372 if api_doc.sort_spec is UNKNOWN: 373 api_doc.sort_spec = []
    374
    375 -def split_init_fields(fields, warnings):
    376 """ 377 Remove the fields related to the constructor from a class docstring 378 fields list. 379 380 @param fields: The fields to process. The list will be modified in place 381 @type fields: C{list} of L{markup.Field} 382 @param warnings: A list to emit processing warnings 383 @type warnings: C{list} 384 @return: The C{fields} items to be applied to the C{__init__} method 385 @rtype: C{list} of L{markup.Field} 386 """ 387 init_fields = [] 388 389 # Split fields in lists according to their argument, keeping order. 390 arg_fields = {} 391 args_order = [] 392 i = 0 393 while i < len(fields): 394 field = fields[i] 395 396 # gather together all the fields with the same arg 397 if field.arg() is not None: 398 arg_fields.setdefault(field.arg(), []).append(fields.pop(i)) 399 args_order.append(field.arg()) 400 else: 401 i += 1 402 403 # Now check that for each argument there is at most a single variable 404 # and a single parameter, and at most a single type for each of them. 405 for arg in args_order: 406 ff = arg_fields.pop(arg, None) 407 if ff is None: 408 continue 409 410 var = tvar = par = tpar = None 411 for field in ff: 412 if field.tag() in VARIABLE_TAGS: 413 if var is None: 414 var = field 415 fields.append(field) 416 else: 417 warnings.append( 418 "There is more than one variable named '%s'" 419 % arg) 420 elif field.tag() in PARAMETER_TAGS: 421 if par is None: 422 par = field 423 init_fields.append(field) 424 else: 425 warnings.append( 426 "There is more than one parameter named '%s'" 427 % arg) 428 429 elif field.tag() == 'type': 430 if var is None and par is None: 431 # type before obj 432 tvar = tpar = field 433 else: 434 if var is not None and tvar is None: 435 tvar = field 436 if par is not None and tpar is None: 437 tpar = field 438 439 elif field.tag() in EXCEPTION_TAGS: 440 init_fields.append(field) 441 442 else: # Unespected field 443 fields.append(field) 444 445 # Put selected types into the proper output lists 446 if tvar is not None: 447 if var is not None: 448 fields.append(tvar) 449 else: 450 pass # [xx] warn about type w/o object? 451 452 if tpar is not None: 453 if par is not None: 454 init_fields.append(tpar) 455 else: 456 pass # [xx] warn about type w/o object? 457 458 return init_fields
    459
    460 -def report_errors(api_doc, docindex, parse_errors, field_warnings):
    461 """A helper function for L{parse_docstring()} that reports any 462 markup warnings and field warnings that we encountered while 463 processing C{api_doc}'s docstring.""" 464 if not parse_errors and not field_warnings: return 465 466 # Get the name of the item containing the error, and the 467 # filename of its containing module. 468 name = api_doc.canonical_name 469 module = api_doc.defining_module 470 if module is not UNKNOWN and module.filename not in (None, UNKNOWN): 471 try: filename = py_src_filename(module.filename) 472 except: filename = module.filename 473 else: 474 filename = '??' 475 476 # [xx] Don't report markup errors for standard builtins. 477 # n.b. that we must use 'is' to compare pyvals here -- if we use 478 # 'in' or '==', then a user __cmp__ method might raise an 479 # exception, or lie. 480 if isinstance(api_doc, ValueDoc) and api_doc != module: 481 if module not in (None, UNKNOWN) and module.pyval is exceptions: 482 return 483 for builtin_val in __builtin__.__dict__.values(): 484 if builtin_val is api_doc.pyval: 485 return 486 487 # Get the start line of the docstring containing the error. 488 startline = api_doc.docstring_lineno 489 if startline in (None, UNKNOWN): 490 startline = introspect_docstring_lineno(api_doc) 491 if startline in (None, UNKNOWN): 492 startline = None 493 494 # Display a block header. 495 header = 'File %s, ' % filename 496 if startline is not None: 497 header += 'line %d, ' % startline 498 header += 'in %s' % name 499 log.start_block(header) 500 501 502 # Display all parse errors. But first, combine any errors 503 # with duplicate description messages. 504 if startline is None: 505 # remove dups, but keep original order: 506 dups = {} 507 for error in parse_errors: 508 message = error.descr() 509 if message not in dups: 510 log.docstring_warning(message) 511 dups[message] = 1 512 else: 513 # Combine line number fields for dup messages: 514 messages = {} # maps message -> list of linenum 515 for error in parse_errors: 516 error.set_linenum_offset(startline) 517 message = error.descr() 518 messages.setdefault(message, []).append(error.linenum()) 519 message_items = messages.items() 520 message_items.sort(lambda a,b:cmp(min(a[1]), min(b[1]))) 521 for message, linenums in message_items: 522 linenums = [n for n in linenums if n is not None] 523 if len(linenums) == 0: 524 log.docstring_warning(message) 525 elif len(linenums) == 1: 526 log.docstring_warning("Line %s: %s" % (linenums[0], message)) 527 else: 528 linenums = ', '.join(['%s' % l for l in linenums]) 529 log.docstring_warning("Lines %s: %s" % (linenums, message)) 530 531 # Display all field warnings. 532 for warning in field_warnings: 533 log.docstring_warning(warning) 534 535 # End the message block. 536 log.end_block()
    537 538 RETURN_PDS = markup.parse('Returns:', markup='epytext') 539 """A ParsedDocstring containing the text 'Returns'. This is used to 540 construct summary descriptions for routines that have empty C{descr}, 541 but non-empty C{return_descr}.""" 542 RETURN_PDS._tree.children[0].attribs['inline'] = True 543 544 ###################################################################### 545 #{ Field Processing Error Messages 546 ###################################################################### 547 548 UNEXPECTED_ARG = '%r did not expect an argument' 549 EXPECTED_ARG = '%r expected an argument' 550 EXPECTED_SINGLE_ARG = '%r expected a single argument' 551 BAD_CONTEXT = 'Invalid context for %r' 552 REDEFINED = 'Redefinition of %s' 553 UNKNOWN_TAG = 'Unknown field tag %r' 554 BAD_PARAM = '@%s for unknown parameter %s' 555 556 ###################################################################### 557 #{ Field Processing 558 ###################################################################### 559
    560 -def process_field(api_doc, docindex, tag, arg, descr):
    561 """ 562 Process a single field, and use it to update C{api_doc}. If 563 C{tag} is the name of a special field, then call its handler 564 function. If C{tag} is the name of a simple field, then use 565 C{process_simple_field} to process it. Otherwise, check if it's a 566 user-defined field, defined in this docstring or the docstring of 567 a containing object; and if so, process it with 568 C{process_simple_field}. 569 570 @param tag: The field's tag, such as C{'author'} 571 @param arg: The field's optional argument 572 @param descr: The description following the field tag and 573 argument. 574 @raise ValueError: If a problem was encountered while processing 575 the field. The C{ValueError}'s string argument is an 576 explanation of the problem, which should be displayed as a 577 warning message. 578 """ 579 # standard special fields 580 if tag in _field_dispatch_table: 581 handler = _field_dispatch_table[tag] 582 handler(api_doc, docindex, tag, arg, descr) 583 return 584 585 # standard simple fields & user-defined fields 586 for field in STANDARD_FIELDS + user_docfields(api_doc, docindex): 587 if tag in field.tags: 588 # [xx] check if it's redefined if it's not multivalue?? 589 if not field.takes_arg: 590 _check(api_doc, tag, arg, expect_arg=False) 591 api_doc.metadata.append((field, arg, descr)) 592 return 593 594 # If we didn't handle the field, then report a warning. 595 raise ValueError(UNKNOWN_TAG % tag)
    596
    597 -def user_docfields(api_doc, docindex):
    598 """ 599 Return a list of user defined fields that can be used for the 600 given object. This list is taken from the given C{api_doc}, and 601 any of its containing C{NamepaceDoc}s. 602 603 @note: We assume here that a parent's docstring will always be 604 parsed before its childrens'. This is indeed the case when we 605 are called via L{docbuilder.build_doc_index()}. If a child's 606 docstring is parsed before its parents, then its parent won't 607 yet have had its C{extra_docstring_fields} attribute 608 initialized. 609 """ 610 docfields = [] 611 # Get any docfields from `api_doc` itself 612 if api_doc.extra_docstring_fields not in (None, UNKNOWN): 613 docfields += api_doc.extra_docstring_fields 614 # Get any docfields from `api_doc`'s ancestors 615 for i in range(len(api_doc.canonical_name)-1, 0, -1): 616 ancestor = docindex.get_valdoc(api_doc.canonical_name[:i]) 617 if ancestor is not None \ 618 and ancestor.extra_docstring_fields not in (None, UNKNOWN): 619 docfields += ancestor.extra_docstring_fields 620 return docfields
    621 622 _field_dispatch_table = {}
    623 -def register_field_handler(handler, *field_tags):
    624 """ 625 Register the given field handler function for processing any 626 of the given field tags. Field handler functions should 627 have the following signature: 628 629 >>> def field_handler(api_doc, docindex, tag, arg, descr): 630 ... '''update api_doc in response to the field.''' 631 632 Where C{api_doc} is the documentation object to update; 633 C{docindex} is a L{DocIndex} that can be used to look up the 634 documentation for related objects; C{tag} is the field tag that 635 was used; C{arg} is the optional argument; and C{descr} is the 636 description following the field tag and argument. 637 """ 638 for field_tag in field_tags: 639 _field_dispatch_table[field_tag] = handler
    640 641 ###################################################################### 642 #{ Field Handler Functions 643 ###################################################################### 644
    645 -def process_summary_field(api_doc, docindex, tag, arg, descr):
    646 """Store C{descr} in C{api_doc.summary}""" 647 _check(api_doc, tag, arg, expect_arg=False) 648 if api_doc.summary is not None: 649 raise ValueError(REDEFINED % tag) 650 api_doc.summary = descr
    651
    652 -def process_include_field(api_doc, docindex, tag, arg, descr):
    653 """Copy the docstring contents from the object named in C{descr}""" 654 _check(api_doc, tag, arg, expect_arg=False) 655 # options: 656 # a. just append the descr to our own 657 # b. append descr and update metadata 658 # c. append descr and process all fields. 659 # in any case, mark any errors we may find as coming from an 660 # imported docstring. 661 662 # how does this interact with documentation inheritance?? 663 raise ValueError('%s not implemented yet' % tag)
    664
    665 -def process_undocumented_field(api_doc, docindex, tag, arg, descr):
    666 """Remove any documentation for the variables named in C{descr}""" 667 _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False) 668 for ident in _descr_to_identifiers(descr): 669 var_name_re = re.compile('^%s$' % ident.replace('*', '(.*)')) 670 for var_name, var_doc in api_doc.variables.items(): 671 if var_name_re.match(var_name): 672 # Remove the variable from `variables`. 673 api_doc.variables.pop(var_name, None) 674 if api_doc.sort_spec is not UNKNOWN: 675 try: api_doc.sort_spec.remove(var_name) 676 except ValueError: pass 677 # For modules, remove any submodules that match var_name_re. 678 if isinstance(api_doc, ModuleDoc): 679 removed = set([m for m in api_doc.submodules 680 if var_name_re.match(m.canonical_name[-1])]) 681 if removed: 682 # Remove the indicated submodules from this module. 683 api_doc.submodules = [m for m in api_doc.submodules 684 if m not in removed] 685 # Remove all ancestors of the indicated submodules 686 # from the docindex root. E.g., if module x 687 # declares y to be undocumented, then x.y.z should 688 # also be undocumented. 689 for elt in docindex.root[:]: 690 for m in removed: 691 if m.canonical_name.dominates(elt.canonical_name): 692 docindex.root.remove(elt)
    693
    694 -def process_group_field(api_doc, docindex, tag, arg, descr):
    695 """Define a group named C{arg} containing the variables whose 696 names are listed in C{descr}.""" 697 _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=True) 698 api_doc.group_specs.append( (arg, _descr_to_identifiers(descr)) )
    699 # [xx] should this also set sort order? 700
    701 -def process_deffield_field(api_doc, docindex, tag, arg, descr):
    702 """Define a new custom field.""" 703 _check(api_doc, tag, arg, expect_arg=True) 704 if api_doc.extra_docstring_fields is UNKNOWN: 705 api_doc.extra_docstring_fields = [] 706 try: 707 docstring_field = _descr_to_docstring_field(arg, descr) 708 docstring_field.varnames.append("__%s__" % arg) 709 api_doc.extra_docstring_fields.append(docstring_field) 710 except ValueError, e: 711 raise ValueError('Bad %s: %s' % (tag, e))
    712
    713 -def process_raise_field(api_doc, docindex, tag, arg, descr):
    714 """Record the fact that C{api_doc} can raise the exception named 715 C{tag} in C{api_doc.exception_descrs}.""" 716 _check(api_doc, tag, arg, context=RoutineDoc, expect_arg='single') 717 try: name = DottedName(arg, strict=True) 718 except DottedName.InvalidDottedName: name = arg 719 api_doc.exception_descrs.append( (name, descr) )
    720
    721 -def process_sort_field(api_doc, docindex, tag, arg, descr):
    722 _check(api_doc, tag, arg, context=NamespaceDoc, expect_arg=False) 723 api_doc.sort_spec = _descr_to_identifiers(descr) + api_doc.sort_spec
    724 725 # [xx] should I notice when they give a type for an unknown var?
    726 -def process_type_field(api_doc, docindex, tag, arg, descr):
    727 # In namespace, "@type var: ..." describes the type of a var. 728 if isinstance(api_doc, NamespaceDoc): 729 _check(api_doc, tag, arg, expect_arg='single') 730 set_var_type(api_doc, arg, descr) 731 732 # For variables & properties, "@type: ..." describes the variable. 733 elif isinstance(api_doc, (VariableDoc, PropertyDoc)): 734 _check(api_doc, tag, arg, expect_arg=False) 735 if api_doc.type_descr is not None: 736 raise ValueError(REDEFINED % tag) 737 api_doc.type_descr = descr 738 739 # For routines, "@type param: ..." describes a parameter. 740 elif isinstance(api_doc, RoutineDoc): 741 _check(api_doc, tag, arg, expect_arg='single') 742 if arg in api_doc.arg_types: 743 raise ValueError(REDEFINED % ('type for '+arg)) 744 api_doc.arg_types[arg] = descr 745 746 else: 747 raise ValueError(BAD_CONTEXT % tag)
    748
    749 -def process_var_field(api_doc, docindex, tag, arg, descr):
    750 _check(api_doc, tag, arg, context=ModuleDoc, expect_arg=True) 751 for ident in re.split('[:;, ] *', arg): 752 set_var_descr(api_doc, ident, descr)
    753
    754 -def process_cvar_field(api_doc, docindex, tag, arg, descr):
    755 # If @cvar is used *within* a variable, then use it as the 756 # variable's description, and treat the variable as a class var. 757 if (isinstance(api_doc, VariableDoc) and 758 isinstance(api_doc.container, ClassDoc)): 759 _check(api_doc, tag, arg, expect_arg=False) 760 api_doc.is_instvar = False 761 api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr) 762 api_doc.summary, api_doc.other_docs = descr.summary() 763 764 # Otherwise, @cvar should be used in a class. 765 else: 766 _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True) 767 for ident in re.split('[:;, ] *', arg): 768 set_var_descr(api_doc, ident, descr) 769 api_doc.variables[ident].is_instvar = False
    770
    771 -def process_ivar_field(api_doc, docindex, tag, arg, descr):
    772 # If @ivar is used *within* a variable, then use it as the 773 # variable's description, and treat the variable as an instvar. 774 if (isinstance(api_doc, VariableDoc) and 775 isinstance(api_doc.container, ClassDoc)): 776 _check(api_doc, tag, arg, expect_arg=False) 777 # require that there be no other descr? 778 api_doc.is_instvar = True 779 api_doc.descr = markup.ConcatenatedDocstring(api_doc.descr, descr) 780 api_doc.summary, api_doc.other_docs = descr.summary() 781 782 # Otherwise, @ivar should be used in a class. 783 else: 784 _check(api_doc, tag, arg, context=ClassDoc, expect_arg=True) 785 for ident in re.split('[:;, ] *', arg): 786 set_var_descr(api_doc, ident, descr) 787 api_doc.variables[ident].is_instvar = True
    788 789 # [xx] '@return: foo' used to get used as a descr if no other 790 # descr was present. is that still true?
    791 -def process_return_field(api_doc, docindex, tag, arg, descr):
    792 _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=False) 793 if api_doc.return_descr is not None: 794 raise ValueError(REDEFINED % 'return value description') 795 api_doc.return_descr = descr
    796
    797 -def process_rtype_field(api_doc, docindex, tag, arg, descr):
    798 _check(api_doc, tag, arg, 799 context=(RoutineDoc, PropertyDoc), expect_arg=False) 800 if isinstance(api_doc, RoutineDoc): 801 if api_doc.return_type is not None: 802 raise ValueError(REDEFINED % 'return value type') 803 api_doc.return_type = descr 804 805 elif isinstance(api_doc, PropertyDoc): 806 _check(api_doc, tag, arg, expect_arg=False) 807 if api_doc.type_descr is not None: 808 raise ValueError(REDEFINED % tag) 809 api_doc.type_descr = descr
    810
    811 -def process_arg_field(api_doc, docindex, tag, arg, descr):
    812 _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True) 813 idents = re.split('[:;, ] *', arg) 814 api_doc.arg_descrs.append( (idents, descr) ) 815 # Check to make sure that the documented parameter(s) are 816 # actually part of the function signature. 817 all_args = api_doc.all_args() 818 if all_args not in (['...'], UNKNOWN): 819 bad_params = ['"%s"' % i for i in idents if i not in all_args] 820 if bad_params: 821 raise ValueError(BAD_PARAM % (tag, ', '.join(bad_params)))
    822
    823 -def process_kwarg_field(api_doc, docindex, tag, arg, descr):
    824 # [xx] these should -not- be checked if they exist.. 825 # and listed separately or not?? 826 _check(api_doc, tag, arg, context=RoutineDoc, expect_arg=True) 827 idents = re.split('[:;, ] *', arg) 828 api_doc.arg_descrs.append( (idents, descr) )
    829 830 register_field_handler(process_group_field, 'group') 831 register_field_handler(process_deffield_field, 'deffield', 'newfield') 832 register_field_handler(process_sort_field, 'sort') 833 register_field_handler(process_summary_field, 'summary') 834 register_field_handler(process_undocumented_field, 'undocumented') 835 register_field_handler(process_include_field, 'include') 836 register_field_handler(process_var_field, 'var', 'variable') 837 register_field_handler(process_type_field, 'type') 838 register_field_handler(process_cvar_field, 'cvar', 'cvariable') 839 register_field_handler(process_ivar_field, 'ivar', 'ivariable') 840 register_field_handler(process_return_field, 'return', 'returns') 841 register_field_handler(process_rtype_field, 'rtype', 'returntype') 842 register_field_handler(process_arg_field, 'arg', 'argument', 843 'parameter', 'param') 844 register_field_handler(process_kwarg_field, 'kwarg', 'keyword', 'kwparam') 845 register_field_handler(process_raise_field, 'raise', 'raises', 846 'except', 'exception') 847 848 # Tags related to function parameters 849 PARAMETER_TAGS = ('arg', 'argument', 'parameter', 'param', 850 'kwarg', 'keyword', 'kwparam') 851 852 # Tags related to variables in a class 853 VARIABLE_TAGS = ('cvar', 'cvariable', 'ivar', 'ivariable') 854 855 # Tags related to exceptions 856 EXCEPTION_TAGS = ('raise', 'raises', 'except', 'exception') 857 858 ###################################################################### 859 #{ Helper Functions 860 ###################################################################### 861
    862 -def check_type_fields(api_doc, field_warnings):
    863 """Check to make sure that all type fields correspond to some 864 documented parameter; if not, append a warning to field_warnings.""" 865 if isinstance(api_doc, RoutineDoc): 866 for arg in api_doc.arg_types: 867 if arg not in api_doc.all_args(): 868 for args, descr in api_doc.arg_descrs: 869 if arg in args: 870 break 871 else: 872 field_warnings.append(BAD_PARAM % ('type', '"%s"' % arg))
    873
    874 -def set_var_descr(api_doc, ident, descr):
    875 if ident not in api_doc.variables: 876 api_doc.variables[ident] = VariableDoc( 877 container=api_doc, name=ident, 878 canonical_name=api_doc.canonical_name+ident) 879 880 var_doc = api_doc.variables[ident] 881 if var_doc.descr not in (None, UNKNOWN): 882 raise ValueError(REDEFINED % ('description for '+ident)) 883 var_doc.descr = descr 884 if var_doc.summary in (None, UNKNOWN): 885 var_doc.summary, var_doc.other_docs = var_doc.descr.summary()
    886
    887 -def set_var_type(api_doc, ident, descr):
    888 if ident not in api_doc.variables: 889 api_doc.variables[ident] = VariableDoc( 890 container=api_doc, name=ident, 891 canonical_name=api_doc.canonical_name+ident) 892 893 var_doc = api_doc.variables[ident] 894 if var_doc.type_descr not in (None, UNKNOWN): 895 raise ValueError(REDEFINED % ('type for '+ident)) 896 var_doc.type_descr = descr
    897
    898 -def _check(api_doc, tag, arg, context=None, expect_arg=None):
    899 if context is not None: 900 if not isinstance(api_doc, context): 901 raise ValueError(BAD_CONTEXT % tag) 902 if expect_arg is not None: 903 if expect_arg == True: 904 if arg is None: 905 raise ValueError(EXPECTED_ARG % tag) 906 elif expect_arg == False: 907 if arg is not None: 908 raise ValueError(UNEXPECTED_ARG % tag) 909 elif expect_arg == 'single': 910 if (arg is None or ' ' in arg): 911 raise ValueError(EXPECTED_SINGLE_ARG % tag) 912 else: 913 assert 0, 'bad value for expect_arg'
    914
    915 -def get_docformat(api_doc, docindex):
    916 """ 917 Return the name of the markup language that should be used to 918 parse the API documentation for the given object. 919 """ 920 # Find the module that defines api_doc. 921 module = api_doc.defining_module 922 # Look up its docformat. 923 if module is not UNKNOWN and module.docformat not in (None, UNKNOWN): 924 docformat = module.docformat 925 else: 926 docformat = DEFAULT_DOCFORMAT 927 # Convert to lower case & strip region codes. 928 try: return docformat.lower().split()[0] 929 except: return DEFAULT_DOCFORMAT
    930
    931 -def unindent_docstring(docstring):
    932 # [xx] copied from inspect.getdoc(); we can't use inspect.getdoc() 933 # itself, since it expects an object, not a string. 934 935 if not docstring: return '' 936 lines = docstring.expandtabs().split('\n') 937 938 # Find minimum indentation of any non-blank lines after first line. 939 margin = sys.maxint 940 for line in lines[1:]: 941 content = len(line.lstrip()) 942 if content: 943 indent = len(line) - content 944 margin = min(margin, indent) 945 # Remove indentation. 946 if lines: 947 lines[0] = lines[0].lstrip() 948 if margin < sys.maxint: 949 for i in range(1, len(lines)): lines[i] = lines[i][margin:] 950 # Remove any trailing (but not leading!) blank lines. 951 while lines and not lines[-1]: 952 lines.pop() 953 #while lines and not lines[0]: 954 # lines.pop(0) 955 return '\n'.join(lines)
    956 957 _IDENTIFIER_LIST_REGEXP = re.compile(r'^[\w.\*]+([\s,:;]\s*[\w.\*]+)*$')
    958 -def _descr_to_identifiers(descr):
    959 """ 960 Given a C{ParsedDocstring} that contains a list of identifiers, 961 return a list of those identifiers. This is used by fields such 962 as C{@group} and C{@sort}, which expect lists of identifiers as 963 their values. To extract the identifiers, the docstring is first 964 converted to plaintext, and then split. The plaintext content of 965 the docstring must be a a list of identifiers, separated by 966 spaces, commas, colons, or semicolons. 967 968 @rtype: C{list} of C{string} 969 @return: A list of the identifier names contained in C{descr}. 970 @type descr: L{markup.ParsedDocstring} 971 @param descr: A C{ParsedDocstring} containing a list of 972 identifiers. 973 @raise ValueError: If C{descr} does not contain a valid list of 974 identifiers. 975 """ 976 idents = descr.to_plaintext(None).strip() 977 idents = re.sub(r'\s+', ' ', idents) 978 if not _IDENTIFIER_LIST_REGEXP.match(idents): 979 raise ValueError, 'Bad Identifier list: %r' % idents 980 rval = re.split('[:;, ] *', idents) 981 return rval
    982
    983 -def _descr_to_docstring_field(arg, descr):
    984 tags = [s.lower() for s in re.split('[:;, ] *', arg)] 985 descr = descr.to_plaintext(None).strip() 986 args = re.split('[:;,] *', descr) 987 if len(args) == 0 or len(args) > 3: 988 raise ValueError, 'Wrong number of arguments' 989 singular = args[0] 990 if len(args) >= 2: plural = args[1] 991 else: plural = None 992 short = 0 993 if len(args) >= 3: 994 if args[2] == 'short': short = 1 995 else: raise ValueError('Bad arg 2 (expected "short")') 996 return DocstringField(tags, singular, plural, short)
    997 998 ###################################################################### 999 #{ Function Signature Extraction 1000 ###################################################################### 1001 1002 # [XX] todo: add optional type modifiers? 1003 _SIGNATURE_RE = re.compile( 1004 # Class name (for builtin methods) 1005 r'^\s*((?P<self>\w+)\.)?' + 1006 # The function name (must match exactly) [XX] not anymore! 1007 r'(?P<func>\w+)' + 1008 # The parameters 1009 r'\((?P<params>(\s*\[?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?'+ 1010 r'(\s*\[?\s*,\s*\]?\s*\*{0,2}[\w\-\.]+(\s*=.+?)?)*\]*)?)\s*\)' + 1011 # The return value (optional) 1012 r'(\s*(->)\s*(?P<return>\S.*?))?'+ 1013 # The end marker 1014 r'\s*(\n|\s+(--|<=+>)\s+|$|\.\s+|\.\n)') 1015 """A regular expression that is used to extract signatures from 1016 docstrings.""" 1017
    1018 -def parse_function_signature(func_doc, doc_source, docformat, parse_errors):
    1019 """ 1020 Construct the signature for a builtin function or method from 1021 its docstring. If the docstring uses the standard convention 1022 of including a signature in the first line of the docstring 1023 (and formats that signature according to standard 1024 conventions), then it will be used to extract a signature. 1025 Otherwise, the signature will be set to a single varargs 1026 variable named C{"..."}. 1027 1028 @param func_doc: The target object where to store parsed signature. Also 1029 container of the docstring to parse if doc_source is C{None} 1030 @type func_doc: L{RoutineDoc} 1031 @param doc_source: Contains the docstring to parse. If C{None}, parse 1032 L{func_doc} docstring instead 1033 @type doc_source: L{APIDoc} 1034 @rtype: C{None} 1035 """ 1036 if doc_source is None: 1037 doc_source = func_doc 1038 1039 # If there's no docstring, then don't do anything. 1040 if not doc_source.docstring: return False 1041 1042 m = _SIGNATURE_RE.match(doc_source.docstring) 1043 if m is None: return False 1044 1045 # Do I want to be this strict? 1046 # Notice that __init__ must match the class name instead, if the signature 1047 # comes from the class docstring 1048 # if not (m.group('func') == func_doc.canonical_name[-1] or 1049 # '_'+m.group('func') == func_doc.canonical_name[-1]): 1050 # log.warning("Not extracting function signature from %s's " 1051 # "docstring, since the name doesn't match." % 1052 # func_doc.canonical_name) 1053 # return False 1054 1055 params = m.group('params') 1056 rtype = m.group('return') 1057 selfparam = m.group('self') 1058 1059 # Extract the parameters from the signature. 1060 func_doc.posargs = [] 1061 func_doc.vararg = None 1062 func_doc.kwarg = None 1063 if func_doc.posarg_defaults is UNKNOWN: 1064 func_doc.posarg_defaults = [] 1065 if params: 1066 # Figure out which parameters are optional. 1067 while '[' in params or ']' in params: 1068 m2 = re.match(r'(.*)\[([^\[\]]+)\](.*)', params) 1069 if not m2: return False 1070 (start, mid, end) = m2.groups() 1071 mid = re.sub(r'((,|^)\s*[\w\-\.]+)', r'\1=...', mid) 1072 params = start+mid+end 1073 1074 params = re.sub(r'=...=' , r'=', params) 1075 for name in params.split(','): 1076 if '=' in name: 1077 (name, default_repr) = name.split('=',1) 1078 default = GenericValueDoc(parse_repr=default_repr) 1079 else: 1080 default = None 1081 name = name.strip() 1082 if name == '...': 1083 func_doc.vararg = '...' 1084 elif name.startswith('**'): 1085 func_doc.kwarg = name[2:] 1086 elif name.startswith('*'): 1087 func_doc.vararg = name[1:] 1088 else: 1089 func_doc.posargs.append(name) 1090 if len(func_doc.posarg_defaults) < len(func_doc.posargs): 1091 func_doc.posarg_defaults.append(default) 1092 elif default is not None: 1093 argnum = len(func_doc.posargs)-1 1094 func_doc.posarg_defaults[argnum] = default 1095 1096 # Extract the return type/value from the signature 1097 if rtype: 1098 func_doc.return_type = markup.parse(rtype, docformat, parse_errors, 1099 inline=True) 1100 1101 # Add the self parameter, if it was specified. 1102 if selfparam: 1103 func_doc.posargs.insert(0, selfparam) 1104 func_doc.posarg_defaults.insert(0, None) 1105 1106 # Remove the signature from the docstring. 1107 doc_source.docstring = doc_source.docstring[m.end():] 1108 1109 # We found a signature. 1110 return True
    1111

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._DocumentPseudoWriter-class.html0000644000175000017500000005213110750103050032206 0ustar pronovicpronovic epydoc.markup.restructuredtext._DocumentPseudoWriter
    Package epydoc :: Package markup :: Module restructuredtext :: Class _DocumentPseudoWriter
    [hide private]
    [frames] | no frames]

    Class _DocumentPseudoWriter

    source code


    A pseudo-writer for the docutils framework, that can be used to access the document itself. The output of _DocumentPseudoWriter is just an empty string; but after it has been used, the most recently processed document is available as the instance variable document

    Instance Methods [hide private]
     
    __init__(self) source code
    call graph 
     
    translate(self)
    Do final translation of self.document into self.output.
    source code
    call graph 

    Inherited from docutils.writers.Writer: assemble_parts, get_transforms, write

    Inherited from docutils.Component: supports

    Class Variables [hide private]

    Inherited from docutils.writers.Writer: component_type, config_section, destination, language, output

    Inherited from docutils.Component: supported

    Inherited from docutils.SettingsSpec: config_section_dependencies, relative_path_settings, settings_default_overrides, settings_defaults, settings_spec

    Inherited from docutils.TransformSpec: default_transforms, unknown_reference_resolvers

    Instance Variables [hide private]
    docutils.nodes.document document
    The document to write (Docutils doctree); set by write.

    Inherited from docutils.writers.Writer: parts

    Method Details [hide private]

    __init__(self)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.writers.Writer.__init__

    translate(self)

    source code 
    call graph 

    Do final translation of self.document into self.output. Called from write. Override in subclasses.

    Usually done with a docutils.nodes.NodeVisitor subclass, in combination with a call to docutils.nodes.Node.walk() or docutils.nodes.Node.walkabout(). The NodeVisitor subclass must support all standard elements (listed in docutils.nodes.node_class_names) and possibly non-standard elements used by the current Reader as well.

    Overrides: docutils.writers.Writer.translate
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docintrospecter-module.html0000644000175000017500000001447010750103050025135 0ustar pronovicpronovic docintrospecter

    Module docintrospecter


    Classes

    Functions

    clear_cache
    get_canonical_name
    get_containing_module
    get_docstring
    get_value_from_filename
    get_value_from_name
    get_value_from_scriptname
    introspect_class
    introspect_docs
    introspect_docstring_lineno
    introspect_module
    introspect_other
    introspect_property
    introspect_routine
    is_classmethod
    is_future_feature
    is_getset
    is_member
    is_property
    is_staticmethod
    isclass
    register_class_type
    register_introspecter
    value_repr
    verify_name

    Variables

    UNDOCUMENTED_CLASS_VARS
    UNDOCUMENTED_MODULE_VARS

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc._Sentinel-class.html0000644000175000017500000001576010750103050024144 0ustar pronovicpronovic epydoc.apidoc._Sentinel
    Package epydoc :: Module apidoc :: Class _Sentinel
    [hide private]
    [frames] | no frames]

    Class _Sentinel

    source code

    A unique value that won't compare equal to any other value. This class is used to create UNKNOWN.

    Instance Methods [hide private]
     
    __init__(self, name) source code
     
    __repr__(self) source code
     
    __nonzero__(self) source code
    epydoc-3.0.1+dfsg/doc/api/toc-epydoc-module.html0000644000175000017500000000262710750103050021730 0ustar pronovicpronovic epydoc

    Module epydoc


    Variables

    DEBUG
    __author__
    __license__
    __url__
    __version__

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.cli.TerminalController-class.html0000644000175000017500000005772310750103050025360 0ustar pronovicpronovic epydoc.cli.TerminalController
    Package epydoc :: Module cli :: Class TerminalController
    [hide private]
    [frames] | no frames]

    Class TerminalController

    source code

    A class that can be used to portably generate formatted output to a terminal. See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116 for documentation. (This is a somewhat stripped-down version.)

    Instance Methods [hide private]
     
    __init__(self, term_stream=sys.stdout) source code
     
    _tigetstr(self, cap_name) source code
    Class Variables [hide private]
      BOL = ''
    Move the cursor to the beginning of the line
      UP = ''
    Move the cursor up one line
      DOWN = ''
    Move the cursor down one line
      LEFT = ''
    Move the cursor left one char
      RIGHT = ''
    Move the cursor right one char
      CLEAR_EOL = ''
    Clear to the end of the line.
      CLEAR_LINE = ''
    Clear the current line; cursor to BOL.
      BOLD = ''
    Turn on bold mode
      NORMAL = ''
    Turn off all modes
      COLS = 75
    Width of the terminal (default to 75)
      WHITE = ''
      YELLOW = ''
      MAGENTA = ''
      RED = ''
      CYAN = ''
      GREEN = ''
      BLUE = ''
      BLACK = ''
      _STRING_CAPABILITIES = ['BOL=cr', 'UP=cuu1', 'DOWN=cud1', 'LEF...
      _COLORS = ['BLACK', 'BLUE', 'GREEN', 'CYAN', 'RED', 'MAGENTA',...
      _ANSICOLORS = ['BLACK', 'RED', 'GREEN', 'YELLOW', 'BLUE', 'MAG...
      FORCE_SIMPLE_TERM = False
    If this is set to true, then new TerminalControllers will assume that the terminal is not capable of doing manipulation of any kind.
    Class Variable Details [hide private]

    _STRING_CAPABILITIES

    Value:
    ['BOL=cr',
     'UP=cuu1',
     'DOWN=cud1',
     'LEFT=cub1',
     'RIGHT=cuf1',
     'CLEAR_EOL=el',
     'BOLD=bold',
     'UNDERLINE=smul',
    ...
    

    _COLORS

    Value:
    ['BLACK',
     'BLUE',
     'GREEN',
     'CYAN',
     'RED',
     'MAGENTA',
     'YELLOW',
     'WHITE']
    

    _ANSICOLORS

    Value:
    ['BLACK',
     'RED',
     'GREEN',
     'YELLOW',
     'BLUE',
     'MAGENTA',
     'CYAN',
     'WHITE']
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docintrospecter._DevNull-class.html0000644000175000017500000003277010750103050025704 0ustar pronovicpronovic epydoc.docintrospecter._DevNull
    Package epydoc :: Module docintrospecter :: Class _DevNull
    [hide private]
    [frames] | no frames]

    Class _DevNull

    source code

    A "file-like" object that discards anything that is written and always reports end-of-file when read. _DevNull is used by _import() to discard output when importing modules; and to ensure that stdin appears closed.

    Instance Methods [hide private]
     
    __init__(self) source code
     
    close(self) source code
     
    flush(self) source code
     
    read(self, size=0) source code
     
    readline(self, size=0) source code
     
    readlines(self, sizehint=0) source code
     
    seek(self, offset, whence=0) source code
     
    tell(self) source code
     
    truncate(self, size=0) source code
     
    write(self, str) source code
     
    writelines(self, sequence) source code
     
    xreadlines(self, sizehint=0) source code
    epydoc-3.0.1+dfsg/doc/api/epydoc.test.util-pysrc.html0000644000175000017500000025571710750103050022764 0ustar pronovicpronovic epydoc.test.util
    Package epydoc :: Package test :: Module util
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.test.util

      1  # 
      2  # epydoc -- Utility functions used by regression tests (*.doctest) 
      3  # Edward Loper 
      4  # 
      5  # Created [01/30/01 05:18 PM] 
      6  # $Id: html.py 1420 2007-01-28 14:19:30Z dvarrazzo $ 
      7  # 
      8   
      9  """ 
     10  Utility functions used by the regression tests (C{*.doctest}). 
     11  """ 
     12  __docformat__ = 'epytext en' 
     13   
     14  import tempfile, re, os, os.path, textwrap, sys 
     15  from epydoc.docbuilder import build_doc, build_doc_index 
     16  from epydoc.docparser import parse_docs 
     17  from epydoc.docintrospecter import introspect_docs 
     18  from epydoc.apidoc import ClassDoc, RoutineDoc 
     19  from epydoc.markup import ParsedDocstring 
     20  from epydoc.docwriter.html import HTMLWriter 
     21   
     22  ###################################################################### 
     23  #{ Test Functions 
     24  ###################################################################### 
     25   
    
    26 -def buildvaluedoc(s):
    27 """ 28 This test function takes a string containing the contents of a 29 module. It writes the string contents to a file, imports the file 30 as a module, and uses build_doc to build documentation, and 31 returns it as a C{ValueDoc} object. 32 """ 33 tmp_dir = write_pystring_to_tmp_dir(s) 34 val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py')) 35 cleanup_tmp_dir(tmp_dir) 36 return val_doc
    37
    38 -def runbuilder(s, attribs='', build=None, exclude=''):
    39 """ 40 This test function takes a string containing the contents of a 41 module. It writes the string contents to a file, imports the file 42 as a module, and uses build_doc to build documentation, and pretty 43 prints the resulting ModuleDoc object. The C{attribs} argument 44 specifies which attributes of the C{APIDoc}s should be displayed. 45 The C{build} argument gives the name of a variable in the module 46 whose documentation should be built, instead of bilding docs for 47 the whole module. 48 """ 49 # Write it to a temp file. 50 tmp_dir = write_pystring_to_tmp_dir(s) 51 # Build it. 52 val_doc = build_doc(os.path.join(tmp_dir, 'epydoc_test.py')) 53 if build: val_doc = val_doc.variables[build].value 54 # Display it. 55 if isinstance(val_doc, ClassDoc): 56 for val in val_doc.variables.values(): 57 if isinstance(val.value, RoutineDoc): 58 fun_to_plain(val.value) 59 s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) 60 s = re.sub(r"(filename = ).*", r"\1...", s) 61 s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s) 62 s = re.sub(r"(<function \w+ at )0x\w+>", r"\1...>", s) 63 s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) 64 print s 65 # Clean up. 66 cleanup_tmp_dir(tmp_dir)
    67
    68 -def runparser(s, attribs='', show=None, exclude=''):
    69 """ 70 This test function takes a string containing the contents of a 71 module, and writes it to a file, uses `parse_docs` to parse it, 72 and pretty prints the resulting ModuleDoc object. The `attribs` 73 argument specifies which attributes of the `APIDoc`s should be 74 displayed. The `show` argument, if specifies, gives the name of 75 the object in the module that should be displayed (but the whole 76 module will always be inspected; this just selects what to 77 display). 78 """ 79 # Write it to a temp file. 80 tmp_dir = write_pystring_to_tmp_dir(s) 81 # Parse it. 82 val_doc = parse_docs(os.path.join(tmp_dir, 'epydoc_test.py')) 83 if show is not None: 84 for name in show.split('.'): 85 if isinstance(val_doc, ClassDoc): 86 val_doc = val_doc.local_variables[name].value 87 else: 88 val_doc = val_doc.variables[name].value 89 # Display it. 90 s = val_doc.pp(include=attribs.split(), exclude=exclude.split()) 91 s = re.sub(r"filename = .*", "filename = ...", s) 92 print s 93 # Clean up. 94 cleanup_tmp_dir(tmp_dir)
    95
    96 -def runintrospecter(s, attribs='', introspect=None, exclude=''):
    97 """ 98 This test function takes a string containing the contents of a 99 module. It writes the string contents to a file, imports the file 100 as a module, and uses C{introspect_docs} to introspect it, and 101 pretty prints the resulting ModuleDoc object. The C{attribs} 102 argument specifies which attributes of the C{APIDoc}s should be 103 displayed. The C{introspect} argument gives the name of a variable 104 in the module whose value should be introspected, instead of 105 introspecting the whole module. 106 """ 107 # Write it to a temp file. 108 tmp_dir = write_pystring_to_tmp_dir(s) 109 # Import it. 110 sys.path.insert(0, tmp_dir) 111 if introspect is None: 112 import epydoc_test as val 113 else: 114 exec("from epydoc_test import %s as val" % introspect) 115 del sys.path[0] 116 # Introspect it. 117 val_doc = introspect_docs(val) 118 # Display it. 119 s = val_doc.pp(include=attribs.split(),exclude=exclude.split()) 120 s = re.sub(r"(filename = ).*", r"\1...", s) 121 s = re.sub(r"(<module 'epydoc_test' from ).*", r'\1...', s) 122 s = re.sub(r"(<function \w+ at )0x\w+>", r"\1...>", s) 123 s = re.sub(r"(<\w+ object at )0x\w+>", r"\1...>", s) 124 print s 125 # Clean up. 126 cleanup_tmp_dir(tmp_dir)
    127 135
    136 -def testencoding(s, introspect=True, parse=True, debug=False):
    137 """ 138 An end-to-end test for unicode encodings. This function takes a 139 given string, writes it to a python file, and processes that 140 file's documentation. It then generates HTML output from the 141 documentation, extracts all docstrings from the generated HTML 142 output, and displays them. (In order to extract & display all 143 docstrings, it monkey-patches the HMTLwriter.docstring_to_html() 144 method.)""" 145 # Monkey-patch docstring_to_html 146 original_docstring_to_html = HTMLWriter.docstring_to_html 147 HTMLWriter.docstring_to_html = print_docstring_as_html 148 149 # Write s to a temporary file. 150 tmp_dir = tempfile.mkdtemp() 151 path = os.path.join(tmp_dir, 'enc_test.py') 152 out = open(path, 'w') 153 out.write(textwrap.dedent(s)) 154 out.close() 155 # Build docs for it 156 docindex = build_doc_index([path], introspect, parse) 157 if docindex is None: return 158 sys.modules.pop('enc_test', None) 159 # Write html output. 160 writer = HTMLWriter(docindex, mark_docstrings=True) 161 writer.write(tmp_dir) 162 for file in os.listdir(tmp_dir): 163 os.unlink(os.path.join(tmp_dir,file)) 164 os.rmdir(tmp_dir) 165 166 # Restore the HTMLWriter class to its original state. 167 HTMLWriter.docstring_to_html = original_docstring_to_html
    168 169 ###################################################################### 170 #{ Helper Functions 171 ###################################################################### 172
    174 tmp_dir = tempfile.mkdtemp() 175 out = open(os.path.join(tmp_dir, 'epydoc_test.py'), 'w') 176 out.write(textwrap.dedent(s)) 177 out.close() 178 return tmp_dir
    179
    180 -def cleanup_tmp_dir(tmp_dir):
    181 os.unlink(os.path.join(tmp_dir, 'epydoc_test.py')) 182 try: os.unlink(os.path.join(tmp_dir, 'epydoc_test.pyc')) 183 except OSError: pass 184 os.rmdir(tmp_dir) 185 sys.modules.pop('epydoc_test', None)
    186
    187 -def to_plain(docstring):
    188 """Conver a parsed docstring into plain text""" 189 if isinstance(docstring, ParsedDocstring): 190 docstring = docstring.to_plaintext(None) 191 return docstring.rstrip()
    192
    193 -def fun_to_plain(val_doc):
    194 """Convert parsed docstrings in text from a RoutineDoc""" 195 for k, v in val_doc.arg_types.items(): 196 val_doc.arg_types[k] = to_plain(v) 197 for i, (k, v) in enumerate(val_doc.arg_descrs): 198 val_doc.arg_descrs[i] = (k, to_plain(v))
    199 211
    212 -def remove_surrogates(s):
    213 """ 214 The following is a helper function, used to convert two-character 215 surrogate sequences into single characters. This is needed 216 because some systems create surrogates but others don't. 217 """ 218 pieces = re.split('(&#\d+;)', s) 219 for i in range(3, len(pieces)-1, 2): 220 if pieces[i-1] != '': continue 221 high,low = int(pieces[i-2][2:-1]), int(pieces[i][2:-1]) 222 if 0xd800 <= high <= 0xdbff and 0xdc00 <= low <= 0xdfff: 223 pieces[i-2] = '&#%d;' % (((high&0x3ff)<<10) + 224 (low&0x3ff) + 0x10000) 225 pieces[i] = '' 226 return ''.join(pieces)
    227

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.dotgraph.DotGraphNode-class.html0000644000175000017500000003524210750103050027111 0ustar pronovicpronovic epydoc.docwriter.dotgraph.DotGraphNode
    Package epydoc :: Package docwriter :: Module dotgraph :: Class DotGraphNode
    [hide private]
    [frames] | no frames]

    Class DotGraphNode

    source code


    Instance Methods [hide private]
     
    __init__(self, label=None, html_label=None, **attribs) source code
    call graph 
     
    __getitem__(self, attr) source code
    call graph 
     
    __setitem__(self, attr, val) source code
    call graph 
     
    to_dotfile(self)
    Return the dot commands that should be used to render this node.
    source code
    call graph 
    Class Variables [hide private]
      _next_id = 0
    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.markup.epytext-module.html0000644000175000017500000001422110750103050024720 0ustar pronovicpronovic epytext

    Module epytext


    Classes

    ColorizingError
    Element
    ParsedEpytextDocstring
    StructuringError
    Token
    TokenizationError

    Functions

    parse
    parse_as_literal
    parse_as_para
    parse_docstring
    pparse
    to_debug
    to_epytext
    to_plaintext

    Variables

    GRAPH_TYPES
    SYMBOLS
    SYMBOL_TO_PLAINTEXT
    __doc__

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.markup-pysrc.html0000644000175000017500000051557510750103050022331 0ustar pronovicpronovic epydoc.markup
    Package epydoc :: Package markup
    [hide private]
    [frames] | no frames]

    Source Code for Package epydoc.markup

      1  # 
      2  # epydoc package file 
      3  # 
      4  # A python documentation Module 
      5  # Edward Loper 
      6  # 
      7  # $Id: __init__.py 1577 2007-03-09 23:26:21Z dvarrazzo $ 
      8  # 
      9   
     10  """ 
     11  Markup language support for docstrings.  Each submodule defines a 
     12  parser for a single markup language.  These parsers convert an 
     13  object's docstring to a L{ParsedDocstring}, a standard intermediate 
     14  representation that can be used to generate output. 
     15  C{ParsedDocstring}s support the following operations: 
     16    - output generation (L{to_plaintext()<ParsedDocstring.to_plaintext>}, 
     17      L{to_html()<ParsedDocstring.to_html>}, and 
     18      L{to_latex()<ParsedDocstring.to_latex>}). 
     19    - Summarization (L{summary()<ParsedDocstring.summary>}). 
     20    - Field extraction (L{split_fields()<ParsedDocstring.split_fields>}). 
     21    - Index term extraction (L{index_terms()<ParsedDocstring.index_terms>}. 
     22   
     23  The L{parse()} function provides a single interface to the 
     24  C{epydoc.markup} package: it takes a docstring and the name of a 
     25  markup language; delegates to the appropriate parser; and returns the 
     26  parsed docstring (along with any errors or warnings that were 
     27  generated). 
     28   
     29  The C{ParsedDocstring} output generation methods (C{to_M{format}()}) 
     30  use a L{DocstringLinker} to link the docstring output with the rest of 
     31  the documentation that epydoc generates.  C{DocstringLinker}s are 
     32  currently responsible for translating two kinds of crossreference: 
     33    - index terms (L{translate_indexterm() 
     34      <DocstringLinker.translate_indexterm>}). 
     35    - identifier crossreferences (L{translate_identifier_xref() 
     36      <DocstringLinker.translate_identifier_xref>}). 
     37   
     38  A parsed docstring's fields can be extracted using the 
     39  L{ParsedDocstring.split_fields()} method.  This method divides a 
     40  docstring into its main body and a list of L{Field}s, each of which 
     41  encodes a single field.  The field's bodies are encoded as 
     42  C{ParsedDocstring}s. 
     43   
     44  Markup errors are represented using L{ParseError}s.  These exception 
     45  classes record information about the cause, location, and severity of 
     46  each error. 
     47   
     48  @sort: parse, ParsedDocstring, Field, DocstringLinker 
     49  @group Errors and Warnings: ParseError 
     50  @group Utility Functions: parse_type_of 
     51  @var SCRWIDTH: The default width with which text will be wrapped 
     52        when formatting the output of the parser. 
     53  @type SCRWIDTH: C{int} 
     54  @var _parse_warnings: Used by L{_parse_warn}. 
     55  """ 
     56  __docformat__ = 'epytext en' 
     57   
     58  import re, types, sys 
     59  from epydoc import log 
     60  from epydoc.util import plaintext_to_html, plaintext_to_latex 
     61  import epydoc 
     62  from epydoc.compat import * 
     63   
     64  ################################################## 
     65  ## Contents 
     66  ################################################## 
     67  # 
     68  # 1. parse() dispatcher 
     69  # 2. ParsedDocstring abstract base class 
     70  # 3. Field class 
     71  # 4. Docstring Linker 
     72  # 5. ParseError exceptions 
     73  # 6. Misc helpers 
     74  # 
     75   
     76  ################################################## 
     77  ## Dispatcher 
     78  ################################################## 
     79   
     80  _markup_language_registry = { 
     81      'restructuredtext': 'epydoc.markup.restructuredtext', 
     82      'epytext': 'epydoc.markup.epytext', 
     83      'plaintext': 'epydoc.markup.plaintext', 
     84      'javadoc': 'epydoc.markup.javadoc', 
     85      } 
     86   
    
    87 -def register_markup_language(name, parse_function):
    88 """ 89 Register a new markup language named C{name}, which can be parsed 90 by the function C{parse_function}. 91 92 @param name: The name of the markup language. C{name} should be a 93 simple identifier, such as C{'epytext'} or C{'restructuredtext'}. 94 Markup language names are case insensitive. 95 96 @param parse_function: A function which can be used to parse the 97 markup language, and returns a L{ParsedDocstring}. It should 98 have the following signature: 99 100 >>> def parse(s, errors): 101 ... 'returns a ParsedDocstring' 102 103 Where: 104 - C{s} is the string to parse. (C{s} will be a unicode 105 string.) 106 - C{errors} is a list; any errors that are generated 107 during docstring parsing should be appended to this 108 list (as L{ParseError} objects). 109 """ 110 _markup_language_registry[name.lower()] = parse_function
    111 112 MARKUP_LANGUAGES_USED = set() 113
    114 -def parse(docstring, markup='plaintext', errors=None, **options):
    115 """ 116 Parse the given docstring, and use it to construct a 117 C{ParsedDocstring}. If any fatal C{ParseError}s are encountered 118 while parsing the docstring, then the docstring will be rendered 119 as plaintext, instead. 120 121 @type docstring: C{string} 122 @param docstring: The docstring to encode. 123 @type markup: C{string} 124 @param markup: The name of the markup language that is used by 125 the docstring. If the markup language is not supported, then 126 the docstring will be treated as plaintext. The markup name 127 is case-insensitive. 128 @param errors: A list where any errors generated during parsing 129 will be stored. If no list is specified, then fatal errors 130 will generate exceptions, and non-fatal errors will be 131 ignored. 132 @type errors: C{list} of L{ParseError} 133 @rtype: L{ParsedDocstring} 134 @return: A L{ParsedDocstring} that encodes the contents of 135 C{docstring}. 136 @raise ParseError: If C{errors} is C{None} and an error is 137 encountered while parsing. 138 """ 139 # Initialize errors list. 140 raise_on_error = (errors is None) 141 if errors == None: errors = [] 142 143 # Normalize the markup language name. 144 markup = markup.lower() 145 146 # Is the markup language valid? 147 if not re.match(r'\w+', markup): 148 _parse_warn('Bad markup language name %r. Treating ' 149 'docstrings as plaintext.' % markup) 150 import epydoc.markup.plaintext as plaintext 151 return plaintext.parse_docstring(docstring, errors, **options) 152 153 # Is the markup language supported? 154 if markup not in _markup_language_registry: 155 _parse_warn('Unsupported markup language %r. Treating ' 156 'docstrings as plaintext.' % markup) 157 import epydoc.markup.plaintext as plaintext 158 return plaintext.parse_docstring(docstring, errors, **options) 159 160 # Get the parse function. 161 parse_docstring = _markup_language_registry[markup] 162 163 # If it's a string, then it names a function to import. 164 if isinstance(parse_docstring, basestring): 165 try: exec('from %s import parse_docstring' % parse_docstring) 166 except ImportError, e: 167 _parse_warn('Error importing %s for markup language %s: %s' % 168 (parse_docstring, markup, e)) 169 import epydoc.markup.plaintext as plaintext 170 return plaintext.parse_docstring(docstring, errors, **options) 171 _markup_language_registry[markup] = parse_docstring 172 173 # Keep track of which markup languages have been used so far. 174 MARKUP_LANGUAGES_USED.add(markup) 175 176 # Parse the docstring. 177 try: parsed_docstring = parse_docstring(docstring, errors, **options) 178 except KeyboardInterrupt: raise 179 except Exception, e: 180 if epydoc.DEBUG: raise 181 log.error('Internal error while parsing a docstring: %s; ' 182 'treating docstring as plaintext' % e) 183 import epydoc.markup.plaintext as plaintext 184 return plaintext.parse_docstring(docstring, errors, **options) 185 186 # Check for fatal errors. 187 fatal_errors = [e for e in errors if e.is_fatal()] 188 if fatal_errors and raise_on_error: raise fatal_errors[0] 189 if fatal_errors: 190 import epydoc.markup.plaintext as plaintext 191 return plaintext.parse_docstring(docstring, errors, **options) 192 193 return parsed_docstring
    194 195 # only issue each warning once: 196 _parse_warnings = {}
    197 -def _parse_warn(estr):
    198 """ 199 Print a warning message. If the given error has already been 200 printed, then do nothing. 201 """ 202 global _parse_warnings 203 if estr in _parse_warnings: return 204 _parse_warnings[estr] = 1 205 log.warning(estr)
    206 207 ################################################## 208 ## ParsedDocstring 209 ##################################################
    210 -class ParsedDocstring:
    211 """ 212 A standard intermediate representation for parsed docstrings that 213 can be used to generate output. Parsed docstrings are produced by 214 markup parsers (such as L{epytext.parse} or L{javadoc.parse}). 215 C{ParsedDocstring}s support several kinds of operation: 216 - output generation (L{to_plaintext()}, L{to_html()}, and 217 L{to_latex()}). 218 - Summarization (L{summary()}). 219 - Field extraction (L{split_fields()}). 220 - Index term extraction (L{index_terms()}. 221 222 The output generation methods (C{to_M{format}()}) use a 223 L{DocstringLinker} to link the docstring output with the rest 224 of the documentation that epydoc generates. 225 226 Subclassing 227 =========== 228 The only method that a subclass is I{required} to implement is 229 L{to_plaintext()}; but it is often useful to override the other 230 methods. The default behavior of each method is described below: 231 - C{to_I{format}}: Calls C{to_plaintext}, and uses the string it 232 returns to generate verbatim output. 233 - C{summary}: Returns C{self} (i.e., the entire docstring). 234 - C{split_fields}: Returns C{(self, [])} (i.e., extracts no 235 fields). 236 - C{index_terms}: Returns C{[]} (i.e., extracts no index terms). 237 238 If and when epydoc adds more output formats, new C{to_I{format}} 239 methods will be added to this base class; but they will always 240 be given a default implementation. 241 """
    242 - def split_fields(self, errors=None):
    243 """ 244 Split this docstring into its body and its fields. 245 246 @return: A tuple C{(M{body}, M{fields})}, where C{M{body}} is 247 the main body of this docstring, and C{M{fields}} is a list 248 of its fields. If the resulting body is empty, return 249 C{None} for the body. 250 @rtype: C{(L{ParsedDocstring}, list of L{Field})} 251 @param errors: A list where any errors generated during 252 splitting will be stored. If no list is specified, then 253 errors will be ignored. 254 @type errors: C{list} of L{ParseError} 255 """ 256 # Default behavior: 257 return self, []
    258
    259 - def summary(self):
    260 """ 261 @return: A pair consisting of a short summary of this docstring and a 262 boolean value indicating whether there is further documentation 263 in addition to the summary. Typically, the summary consists of the 264 first sentence of the docstring. 265 @rtype: (L{ParsedDocstring}, C{bool}) 266 """ 267 # Default behavior: 268 return self, False
    269
    270 - def concatenate(self, other):
    271 """ 272 @return: A new parsed docstring containing the concatination 273 of this docstring and C{other}. 274 @raise ValueError: If the two parsed docstrings are 275 incompatible. 276 """ 277 return ConcatenatedDocstring(self, other)
    278
    279 - def __add__(self, other): return self.concatenate(other)
    280
    281 - def to_html(self, docstring_linker, **options):
    282 """ 283 Translate this docstring to HTML. 284 285 @param docstring_linker: An HTML translator for crossreference 286 links into and out of the docstring. 287 @type docstring_linker: L{DocstringLinker} 288 @param options: Any extra options for the output. Unknown 289 options are ignored. 290 @return: An HTML fragment that encodes this docstring. 291 @rtype: C{string} 292 """ 293 # Default behavior: 294 plaintext = plaintext_to_html(self.to_plaintext(docstring_linker)) 295 return '<pre class="literalblock">\n%s\n</pre>\n' % plaintext
    296
    297 - def to_latex(self, docstring_linker, **options):
    298 """ 299 Translate this docstring to LaTeX. 300 301 @param docstring_linker: A LaTeX translator for crossreference 302 links into and out of the docstring. 303 @type docstring_linker: L{DocstringLinker} 304 @param options: Any extra options for the output. Unknown 305 options are ignored. 306 @return: A LaTeX fragment that encodes this docstring. 307 @rtype: C{string} 308 """ 309 # Default behavior: 310 plaintext = plaintext_to_latex(self.to_plaintext(docstring_linker)) 311 return '\\begin{alltt}\n%s\\end{alltt}\n\n' % plaintext
    312
    313 - def to_plaintext(self, docstring_linker, **options):
    314 """ 315 Translate this docstring to plaintext. 316 317 @param docstring_linker: A plaintext translator for 318 crossreference links into and out of the docstring. 319 @type docstring_linker: L{DocstringLinker} 320 @param options: Any extra options for the output. Unknown 321 options are ignored. 322 @return: A plaintext fragment that encodes this docstring. 323 @rtype: C{string} 324 """ 325 raise NotImplementedError, 'ParsedDocstring.to_plaintext()'
    326
    327 - def index_terms(self):
    328 """ 329 @return: The list of index terms that are defined in this 330 docstring. Each of these items will be added to the index 331 page of the documentation. 332 @rtype: C{list} of C{ParsedDocstring} 333 """ 334 # Default behavior: 335 return []
    336 337 ################################################## 338 ## Concatenated Docstring 339 ##################################################
    341 - def __init__(self, *parsed_docstrings):
    342 self._parsed_docstrings = [pds for pds in parsed_docstrings 343 if pds is not None]
    344
    345 - def split_fields(self, errors=None):
    346 bodies = [] 347 fields = [] 348 for doc in self._parsed_docstrings: 349 b,f = doc.split_fields() 350 bodies.append(b) 351 fields.extend(f) 352 353 return ConcatenatedDocstring(*bodies), fields
    354
    355 - def summary(self):
    356 return self._parsed_docstrings[0].summary()
    357
    358 - def to_html(self, docstring_linker, **options):
    359 htmlstring = '' 360 for doc in self._parsed_docstrings: 361 htmlstring += doc.to_html(docstring_linker, **options) 362 return htmlstring
    363
    364 - def to_latex(self, docstring_linker, **options):
    365 latexstring = '' 366 for doc in self._parsed_docstrings: 367 latexstring += doc.to_latex(docstring_linker, **options) 368 return latexstring
    369
    370 - def to_plaintext(self, docstring_linker, **options):
    371 textstring = '' 372 for doc in self._parsed_docstrings: 373 textstring += doc.to_plaintext(docstring_linker, **options) 374 return textstring
    375
    376 - def index_terms(self):
    377 terms = [] 378 for doc in self._parsed_docstrings: 379 terms += doc.index_terms() 380 return terms
    381 382 ################################################## 383 ## Fields 384 ##################################################
    385 -class Field:
    386 """ 387 The contents of a docstring's field. Docstring fields are used 388 to describe specific aspects of an object, such as a parameter of 389 a function or the author of a module. Each field consists of a 390 tag, an optional argument, and a body: 391 - The tag specifies the type of information that the field 392 encodes. 393 - The argument specifies the object that the field describes. 394 The argument may be C{None} or a C{string}. 395 - The body contains the field's information. 396 397 Tags are automatically downcased and stripped; and arguments are 398 automatically stripped. 399 """
    400 - def __init__(self, tag, arg, body):
    401 self._tag = tag.lower().strip() 402 if arg is None: self._arg = None 403 else: self._arg = arg.strip() 404 self._body = body
    405
    406 - def tag(self):
    407 """ 408 @return: This field's tag. 409 @rtype: C{string} 410 """ 411 return self._tag
    412
    413 - def arg(self):
    414 """ 415 @return: This field's argument, or C{None} if this field has 416 no argument. 417 @rtype: C{string} or C{None} 418 """ 419 return self._arg
    420
    421 - def body(self):
    422 """ 423 @return: This field's body. 424 @rtype: L{ParsedDocstring} 425 """ 426 return self._body
    427
    428 - def __repr__(self):
    429 if self._arg is None: 430 return '<Field @%s: ...>' % self._tag 431 else: 432 return '<Field @%s %s: ...>' % (self._tag, self._arg)
    433 434 ################################################## 435 ## Docstring Linker (resolves crossreferences) 436 ##################################################
    437 -class DocstringLinker:
    438 """ 439 A translator for crossreference links into and out of a 440 C{ParsedDocstring}. C{DocstringLinker} is used by 441 C{ParsedDocstring} to convert these crossreference links into 442 appropriate output formats. For example, 443 C{DocstringLinker.to_html} expects a C{DocstringLinker} that 444 converts crossreference links to HTML. 445 """
    446 - def translate_indexterm(self, indexterm):
    447 """ 448 Translate an index term to the appropriate output format. The 449 output will typically include a crossreference anchor. 450 451 @type indexterm: L{ParsedDocstring} 452 @param indexterm: The index term to translate. 453 @rtype: C{string} 454 @return: The translated index term. 455 """ 456 raise NotImplementedError, 'DocstringLinker.translate_indexterm()'
    457
    458 - def translate_identifier_xref(self, identifier, label=None):
    459 """ 460 Translate a crossreference link to a Python identifier to the 461 appropriate output format. The output will typically include 462 a reference or pointer to the crossreference target. 463 464 @type identifier: C{string} 465 @param identifier: The name of the Python identifier that 466 should be linked to. 467 @type label: C{string} or C{None} 468 @param label: The label that should be used for the identifier, 469 if it's different from the name of the identifier. 470 @rtype: C{string} 471 @return: The translated crossreference link. 472 """ 473 raise NotImplementedError, 'DocstringLinker.translate_xref()'
    474 475 ################################################## 476 ## ParseError exceptions 477 ################################################## 478
    479 -class ParseError(Exception):
    480 """ 481 The base class for errors generated while parsing docstrings. 482 483 @ivar _linenum: The line on which the error occured within the 484 docstring. The linenum of the first line is 0. 485 @type _linenum: C{int} 486 @ivar _offset: The line number where the docstring begins. This 487 offset is added to C{_linenum} when displaying the line number 488 of the error. Default value: 1. 489 @type _offset: C{int} 490 @ivar _descr: A description of the error. 491 @type _descr: C{string} 492 @ivar _fatal: True if this is a fatal error. 493 @type _fatal: C{boolean} 494 """
    495 - def __init__(self, descr, linenum=None, is_fatal=1):
    496 """ 497 @type descr: C{string} 498 @param descr: A description of the error. 499 @type linenum: C{int} 500 @param linenum: The line on which the error occured within 501 the docstring. The linenum of the first line is 0. 502 @type is_fatal: C{boolean} 503 @param is_fatal: True if this is a fatal error. 504 """ 505 self._descr = descr 506 self._linenum = linenum 507 self._fatal = is_fatal 508 self._offset = 1
    509
    510 - def is_fatal(self):
    511 """ 512 @return: true if this is a fatal error. If an error is fatal, 513 then epydoc should ignore the output of the parser, and 514 parse the docstring as plaintext. 515 @rtype: C{boolean} 516 """ 517 return self._fatal
    518
    519 - def linenum(self):
    520 """ 521 @return: The line number on which the error occured (including 522 any offset). If the line number is unknown, then return 523 C{None}. 524 @rtype: C{int} or C{None} 525 """ 526 if self._linenum is None: return None 527 else: return self._offset + self._linenum
    528
    529 - def set_linenum_offset(self, offset):
    530 """ 531 Set the line number offset for this error. This offset is the 532 line number where the docstring begins. This offset is added 533 to C{_linenum} when displaying the line number of the error. 534 535 @param offset: The new line number offset. 536 @type offset: C{int} 537 @rtype: C{None} 538 """ 539 self._offset = offset
    540
    541 - def descr(self):
    542 return self._descr
    543
    544 - def __str__(self):
    545 """ 546 Return a string representation of this C{ParseError}. This 547 multi-line string contains a description of the error, and 548 specifies where it occured. 549 550 @return: the informal representation of this C{ParseError}. 551 @rtype: C{string} 552 """ 553 if self._linenum is not None: 554 return 'Line %s: %s' % (self._linenum+self._offset, self.descr()) 555 else: 556 return self.descr()
    557
    558 - def __repr__(self):
    559 """ 560 Return the formal representation of this C{ParseError}. 561 C{ParseError}s have formal representations of the form:: 562 <ParseError on line 12> 563 564 @return: the formal representation of this C{ParseError}. 565 @rtype: C{string} 566 """ 567 if self._linenum is None: 568 return '<ParseError on line %d' % self._offset 569 else: 570 return '<ParseError on line %d>' % (self._linenum+self._offset)
    571
    572 - def __cmp__(self, other):
    573 """ 574 Compare two C{ParseError}s, based on their line number. 575 - Return -1 if C{self.linenum<other.linenum} 576 - Return +1 if C{self.linenum>other.linenum} 577 - Return 0 if C{self.linenum==other.linenum}. 578 The return value is undefined if C{other} is not a 579 ParseError. 580 581 @rtype: C{int} 582 """ 583 if not isinstance(other, ParseError): return -1000 584 return cmp(self._linenum+self._offset, 585 other._linenum+other._offset)
    586 587 ################################################## 588 ## Misc helpers 589 ################################################## 590 # These are used by multiple markup parsers 591
    592 -def parse_type_of(obj):
    593 """ 594 @return: A C{ParsedDocstring} that encodes the type of the given 595 object. 596 @rtype: L{ParsedDocstring} 597 @param obj: The object whose type should be returned as DOM document. 598 @type obj: any 599 """ 600 # This is a bit hackish; oh well. :) 601 from epydoc.markup.epytext import ParsedEpytextDocstring 602 from xml.dom.minidom import Document 603 doc = Document() 604 epytext = doc.createElement('epytext') 605 para = doc.createElement('para') 606 doc.appendChild(epytext) 607 epytext.appendChild(para) 608 609 if type(obj) is types.InstanceType: 610 link = doc.createElement('link') 611 name = doc.createElement('name') 612 target = doc.createElement('target') 613 para.appendChild(link) 614 link.appendChild(name) 615 link.appendChild(target) 616 name.appendChild(doc.createTextNode(str(obj.__class__.__name__))) 617 target.appendChild(doc.createTextNode(str(obj.__class__))) 618 else: 619 code = doc.createElement('code') 620 para.appendChild(code) 621 code.appendChild(doc.createTextNode(type(obj).__name__)) 622 return ParsedEpytextDocstring(doc)
    623
    epydoc-3.0.1+dfsg/doc/api/epydoc.gui.GUILogger-class.html0000644000175000017500000005554410750103050023341 0ustar pronovicpronovic epydoc.gui.GUILogger
    Package epydoc :: Module gui :: Class GUILogger
    [hide private]
    [frames] | no frames]

    Class GUILogger

    source code


    Instance Methods [hide private]
     
    __init__(self, progress, cancel) source code
     
    clear(self) source code
     
    log(self, level, message)
    Display a message.
    source code
     
    start_block(self, header)
    Start a new message block.
    source code
     
    end_block(self)
    End a warning block.
    source code
     
    start_progress(self, header=None)
    Begin displaying progress for a new task.
    source code
     
    end_progress(self)
    Finish off the display of progress for the current task.
    source code
     
    progress(self, percent, message='')
    Update the progress display.
    source code
     
    read(self) source code

    Inherited from log.Logger: close

    Class Variables [hide private]
      _STAGES = [40, 7, 1, 3, 1, 30, 1, 2, 100]
    Method Details [hide private]

    log(self, level, message)

    source code 

    Display a message.

    Parameters:
    • message - The message string to display. message may contain newlines, but does not need to end in a newline.
    • level - An integer value indicating the severity of the message.
    Overrides: log.Logger.log
    (inherited documentation)

    start_block(self, header)

    source code 

    Start a new message block. Any calls to info(), warning(), or error() that occur between a call to start_block and a corresponding call to end_block will be grouped together, and displayed with a common header. start_block can be called multiple times (to form nested blocks), but every call to start_block must be balanced by a call to end_block.

    Overrides: log.Logger.start_block
    (inherited documentation)

    end_block(self)

    source code 

    End a warning block. See start_block for details.

    Overrides: log.Logger.end_block
    (inherited documentation)

    start_progress(self, header=None)

    source code 

    Begin displaying progress for a new task. header is a description of the task for which progress is being reported. Each call to start_progress must be followed by a call to end_progress (with no intervening calls to start_progress).

    Overrides: log.Logger.start_progress
    (inherited documentation)

    end_progress(self)

    source code 

    Finish off the display of progress for the current task. See start_progress for more information.

    Overrides: log.Logger.end_progress
    (inherited documentation)

    progress(self, percent, message='')

    source code 

    Update the progress display.

    Parameters:
    • percent - A float from 0.0 to 1.0, indicating how much progress has been made.
    • message - A message indicating the most recent action that contributed towards that progress.
    Overrides: log.Logger.progress
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_colorize.PythonSourceColorizer-class.html0000644000175000017500000021044010750103050032163 0ustar pronovicpronovic epydoc.docwriter.html_colorize.PythonSourceColorizer
    Package epydoc :: Package docwriter :: Module html_colorize :: Class PythonSourceColorizer
    [hide private]
    [frames] | no frames]

    Class PythonSourceColorizer

    source code

    A class that renders a python module's source code into HTML pages. These HTML pages are intended to be provided along with the API documentation for a module, in case a user wants to learn more about a particular object by examining its source code. Links are therefore generated from the API documentation to the source code pages, and from the source code pages back into the API documentation.

    The HTML generated by PythonSourceColorizer has several notable features:

    • CSS styles are used to color tokens according to their type. (See CSS_CLASSES for a list of the different token types that are identified).
    • Line numbers are included to the left of each line.
    • The first line of each class and function definition includes a link to the API source documentation for that object.
    • The first line of each class and function definition includes an anchor that can be used to link directly to that class or function.
    • If javascript is enabled, and the page is loaded using the anchor for a class or function (i.e., if the url ends in '#<name>'), then that class or function will automatically be highlighted; and all other classes and function definition blocks will be 'collapsed'. These collapsed blocks can be expanded by clicking on them.
    • Unicode input is supported (including automatic detection of 'coding:' declarations).
    Instance Methods [hide private]
     
    __init__(self, module_filename, module_name, docindex=None, url_func=None, name_to_docs=None, tab_width=8)
    Create a new HTML colorizer for the specified module.
    source code
    call graph 
     
    find_line_offsets(self)
    Construct the line_offsets table from self.text.
    source code
    call graph 
     
    lineno_to_html(self) source code
    call graph 
     
    colorize(self)
    Return an HTML string that renders the source code for the module that was specified in the constructor.
    source code
    call graph 
     
    tokeneater(self, toktype, toktext, (srow, scol), (erow, ecol), line)
    A callback function used by tokenize.tokenize to handle each token in the module.
    source code
    call graph 
     
    handle_line(self, line)
    Render a single logical line from the module, and write the generated HTML to self.out.
    source code
    call graph 
     
    context_name(self, extra=None) source code
    call graph 
     
    doclink(self, name, docs) source code
    call graph 
     
    doc_descr(self, doc, context) source code
    call graph 
     
    doc_kind(self, doc) source code
    call graph 
     
    mark_def(self, s, name) source code
    call graph 
     
    is_docstring(self, line, i) source code
    call graph 
     
    add_line_numbers(self, s, css_class) source code
    call graph 
     
    name2url(self, class_name, func_name=None) source code
    call graph 
    Class Variables [hide private]
      CSS_CLASSES = {'@': 'py-decorator', 'BASECLASS': 'py-base-clas...
    A look-up table that is used to determine which CSS class should be used to colorize a given token.
      START_DEF_BLOCK = '<div id="%s-collapsed" style="display:none;...
    HTML code for the beginning of a collapsable function or class definition block.
      END_DEF_BLOCK = '</div>'
    HTML code for the end of a collapsable function or class definition block.
      UNICODE_CODING_RE = re.compile(r'.*?\n?.*?coding[:=]\s*([-\w\....
    A regular expression used to pick out the unicode encoding for the source file.
      ADD_DEF_BLOCKS = True
    A configuration constant, used to determine whether or not to add collapsable <div> elements for definition blocks.
      ADD_LINE_NUMBERS = True
    A configuration constant, used to determine whether or not to add line numbers.
      ADD_TOOLTIPS = True
    A configuration constant, used to determine whether or not to add tooltips for linked names.
      GUESS_LINK_TARGETS = False
    If true, then try to guess which target is appropriate for linked names; if false, then always open a div asking the user which one they want.
      _next_uid = 0
      _FIX_DECORATOR_RE = re.compile(r'(?m)((?:^<a name="L\d+"></a><...
    A regexp used to move the <div> that marks the beginning of a function or method to just before the decorators.
    Instance Variables [hide private]
      module_filename
    The filename of the module we're colorizing.
      module_name
    The dotted name of the module we're colorizing.
      docindex
    A docindex, used to create href links from identifiers to the API documentation for their values.
      name_to_docs
    A mapping from short names to lists of ValueDoc, used to decide which values an identifier might map to when creating href links from identifiers to the API docs for their values.
      url_func
    A function that maps APIDoc -> URL, used to create href links from identifiers to the API documentation for their values.
      pos
    The index in text of the last character of the last token we've processed.
      line_offsets
    A list that maps line numbers to character offsets in text.
      cur_line
    A list of (toktype, toktext) for all tokens on the logical line that we are currently processing.
      context
    A list of the names of the class or functions that include the current block.
      context_types
    A list, corresponding one-to-one with self.context, indicating the type of each entry.
      indents
    A list of indentation strings for each of the current block's indents.
      lineno
    The line number of the line we're currently processing.
      def_name
    The name of the class or function whose definition started on the previous logical line, or None if the previous logical line was not a class or function definition.
      def_type
    The type of the class or function whose definition started on the previous logical line, or None if the previous logical line was not a class or function definition.
      tab_width
    The number of spaces to replace each tab in source code with
    Method Details [hide private]

    __init__(self, module_filename, module_name, docindex=None, url_func=None, name_to_docs=None, tab_width=8)
    (Constructor)

    source code 
    call graph 

    Create a new HTML colorizer for the specified module.

    Parameters:
    • module_filename - The name of the file containing the module; its text will be loaded from this file.
    • module_name - The dotted name of the module; this will be used to create links back into the API source documentation.

    tokeneater(self, toktype, toktext, (srow, scol), (erow, ecol), line)

    source code 
    call graph 

    A callback function used by tokenize.tokenize to handle each token in the module. tokeneater collects tokens into the self.cur_line list until a complete logical line has been formed; and then calls handle_line to process that line.

    handle_line(self, line)

    source code 
    call graph 

    Render a single logical line from the module, and write the generated HTML to self.out.

    Parameters:
    • line - A single logical line, encoded as a list of (toktype,tokttext) pairs corresponding to the tokens in the line.

    Class Variable Details [hide private]

    CSS_CLASSES

    A look-up table that is used to determine which CSS class should be used to colorize a given token. The following keys may be used:

    • Any token name (e.g., 'STRING')
    • Any operator token (e.g., '=' or '@').
    • 'KEYWORD' -- Python keywords such as 'for' and 'if'
    • 'DEFNAME' -- the name of a class or function at the top of its definition statement.
    • 'BASECLASS' -- names of base classes at the top of a class definition statement.
    • 'PARAM' -- function parameters
    • 'DOCSTRING' -- docstrings
    • 'DECORATOR' -- decorator names

    If no CSS class can be found for a given token, then it won't be marked with any CSS class.

    Value:
    {'@': 'py-decorator',
     'BASECLASS': 'py-base-class',
     'COMMENT': 'py-comment',
     'DECORATOR': 'py-decorator',
     'DEFNAME': 'py-def-name',
     'DOCSTRING': 'py-docstring',
     'KEYWORD': 'py-keyword',
     'NAME': 'py-name',
    ...
    

    START_DEF_BLOCK

    HTML code for the beginning of a collapsable function or class definition block. The block contains two <div>...</div> elements -- a collapsed version and an expanded version -- and only one of these elements is visible at any given time. By default, all definition blocks are expanded.

    This string should be interpolated with the following values:

     (name, indentation, name)
    

    Where name is the anchor name for the function or class; and indentation is a string of whitespace used to indent the ellipsis marker in the collapsed version.

    Value:
    '<div id="%s-collapsed" style="display:none;" pad="%s" indent="%s"></d\
    iv><div id="%s-expanded">'
    

    UNICODE_CODING_RE

    A regular expression used to pick out the unicode encoding for the source file.

    Value:
    re.compile(r'.*?\n?.*?coding[:=]\s*([-\w\.]+)')
    

    _FIX_DECORATOR_RE

    A regexp used to move the <div> that marks the beginning of a function or method to just before the decorators.

    Value:
    re.compile(r'(?m)((?:^<a name="L\d+"></a><tt class="py-lineno">\s*\d+<\
    /tt>\s*<tt class="py-line">(?:<tt class="py-decorator">.*|\s*</tt>|\s*\
    <tt class="py-comment">.*)\n)+)(<a name="\w+"></a><div id="\w+-def">)'\
    )
    

    Instance Variable Details [hide private]

    line_offsets

    A list that maps line numbers to character offsets in text. In particular, line i begins at character line_offset[i] in text. Since line numbers begin at 1, the first element of line_offsets is None.

    cur_line

    A list of (toktype, toktext) for all tokens on the logical line that we are currently processing. Once a complete line of tokens has been collected in cur_line, it is sent to handle_line for processing.

    context

    A list of the names of the class or functions that include the current block. context has one element for each level of indentation; context[i] is the name of the class or function defined by the ith level of indentation, or None if that level of indentation doesn't correspond to a class or function definition.

    context_types

    A list, corresponding one-to-one with self.context, indicating the type of each entry. Each element of context_types is one of: 'func', 'class', None.

    indents

    A list of indentation strings for each of the current block's indents. I.e., the current total indentation can be found by taking ''.join(self.indents).

    def_type

    The type of the class or function whose definition started on the previous logical line, or None if the previous logical line was not a class or function definition. Can be 'func', 'class', None.


    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.DocIndex-class.html0000644000175000017500000015206210750103050023716 0ustar pronovicpronovic epydoc.apidoc.DocIndex
    Package epydoc :: Module apidoc :: Class DocIndex
    [hide private]
    [frames] | no frames]

    Class DocIndex

    source code

    [xx] out of date.

    An index that .. hmm... it *can't* be used to access some things, cuz they're not at the root level. Do I want to add them or what? And if so, then I have a sort of a new top level. hmm.. so basically the question is what to do with a name that's not in the root var's name space. 2 types:

    • entirely outside (eg os.path)
    • inside but not known (eg a submodule that we didn't look at?)
    • container of current thing not examined?

    An index of all the APIDoc objects that can be reached from a root set of ValueDocs.

    The members of this index can be accessed by dotted name. In particular, DocIndex defines two mappings, accessed via the get_vardoc() and get_valdoc() methods, which can be used to access VariableDocs or ValueDocs respectively by name. (Two separate mappings are necessary because a single name can be used to refer to both a variable and to the value contained by that variable.)

    Additionally, the index defines two sets of ValueDocs: "reachable ValueDocs" and "contained ValueDocs". The reachable ValueDocs are defined as the set of all ValueDocs that can be reached from the root set by following any sequence of pointers to ValueDocs or VariableDocs. The contained ValueDocs are defined as the set of all ValueDocs that can be reached from the root set by following only the ValueDoc pointers defined by non-imported VariableDocs. For example, if the root set contains a module m, then the contained ValueDocs includes the ValueDocs for any functions, variables, or classes defined in that module, as well as methods and variables defined in classes defined in the module. The reachable ValueDocs includes all of those ValueDocs, as well as ValueDocs for any values imported into the module, and base classes for classes defined in the module.

    Instance Methods [hide private]
     
    __init__(self, root)
    Create a new documentation index, based on the given root set of ValueDocs.
    source code
    call graph 
     
    get_vardoc(self, name)
    Return the VariableDoc with the given name, or None if this index does not contain a VariableDoc with the given name.
    source code
    call graph 
     
    get_valdoc(self, name)
    Return the ValueDoc with the given name, or None if this index does not contain a ValueDoc with the given name.
    source code
    call graph 
     
    _get(self, name)
    A helper function that's used to implement get_vardoc() and get_valdoc().
    source code
    call graph 
     
    _get_from(self, val_doc, identifier) source code
    call graph 
     
    find(self, name, context)
    Look for an APIDoc named name, relative to context.
    source code
    call graph 
    dict from str to ClassDoc or list
    _get_module_classes(self, docs)
    Gather all the classes defined in a list of modules.
    source code
    call graph 
     
    reachable_valdocs(self, **filters)
    Return a list of all ValueDocs that can be reached, directly or indirectly from this DocIndex's root set.
    source code
    call graph 
     
    container(self, api_doc)
    Return the ValueDoc that contains the given APIDoc, or None if its container is not in the index.
    source code
    call graph 
     
    read_profiling_info(self, profile_stats)
    Initialize the callers and callees variables, given a Stat object from the pstats module.
    source code
     
    _update_funcid_to_doc(self, profile_stats)
    Update the dictionary mapping from pstat.Stat funciton ids to RoutineDocs.
    source code
    Instance Variables [hide private]
    list root
    The list of ValueDocs to document.
    dict from str to ClassDoc or list mlclasses
    A mapping from class names to ClassDoc.
    list of RoutineDoc callers
    A dictionary mapping from RoutineDocs in this index to lists of RoutineDocs for the routine's callers.
    list of RoutineDoc callees
    A dictionary mapping from RoutineDocs in this index to lists of RoutineDocs for the routine's callees.
      _funcid_to_doc
    A mapping from profile function ids to corresponding APIDoc objects.
      _container_cache
    A cache for the container() method, to increase speed.
      _get_cache
    A cache for the get_vardoc() and get_valdoc() methods, to increase speed.
    Method Details [hide private]

    __init__(self, root)
    (Constructor)

    source code 
    call graph 

    Create a new documentation index, based on the given root set of ValueDocs. If any APIDocs reachable from the root set does not have a canonical name, then it will be assigned one. etc.

    Parameters:
    • root - A list of ValueDocs.

    find(self, name, context)

    source code 
    call graph 

    Look for an APIDoc named name, relative to context. Return the APIDoc if one is found; otherwise, return None. find looks in the following places, in order:

    • Function parameters (if one matches, return None)
    • All enclosing namespaces, from closest to furthest.
    • If name starts with 'self', then strip it off and look for the remaining part of the name using find
    • Builtins
    • Parameter attributes
    • Classes at module level (if the name is not ambiguous)
    Parameters:

    _get_module_classes(self, docs)

    source code 
    call graph 

    Gather all the classes defined in a list of modules.

    Very often people refers to classes only by class name, even if they are not imported in the namespace. Linking to such classes will fail if we look for them only in nested namespaces. Allow them to retrieve only by name.

    Parameters:
    • docs (list of APIDoc) - containers of the objects to collect
    Returns: dict from str to ClassDoc or list
    mapping from objects name to the object(s) with that name

    reachable_valdocs(self, **filters)

    source code 
    call graph 

    Return a list of all ValueDocs that can be reached, directly or indirectly from this DocIndex's root set.

    Parameters:
    • filters - A set of filters that can be used to prevent reachable_valdocs from following specific link types when looking for ValueDocs that can be reached from the root set. See APIDoc.apidoc_links for a more complete description.

    read_profiling_info(self, profile_stats)

    source code 

    Initialize the callers and callees variables, given a Stat object from the pstats module.

    Warning: This method uses undocumented data structures inside of profile_stats.

    _update_funcid_to_doc(self, profile_stats)

    source code 

    Update the dictionary mapping from pstat.Stat funciton ids to RoutineDocs. pstat.Stat function ids are tuples of (filename, lineno, funcname).


    Instance Variable Details [hide private]

    mlclasses

    A mapping from class names to ClassDoc. Contains classes defined at module level for modules in root and which can be used as fallback by find() if looking in containing namespaces fails.

    Type:
    dict from str to ClassDoc or list

    callers

    A dictionary mapping from RoutineDocs in this index to lists of RoutineDocs for the routine's callers. This dictionary is initialized by calling read_profiling_info().

    Type:
    list of RoutineDoc

    callees

    A dictionary mapping from RoutineDocs in this index to lists of RoutineDocs for the routine's callees. This dictionary is initialized by calling read_profiling_info().

    Type:
    list of RoutineDoc

    _funcid_to_doc

    A mapping from profile function ids to corresponding APIDoc objects. A function id is a tuple of the form (filename, lineno, funcname). This is used to update the callers and callees variables.


    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html.HTMLWriter-class.html0000644000175000017500000115774310750103050025704 0ustar pronovicpronovic epydoc.docwriter.html.HTMLWriter
    Package epydoc :: Package docwriter :: Module html :: Class HTMLWriter
    [hide private]
    [frames] | no frames]

    Class HTMLWriter

    source code

    Instance Methods [hide private]
     
    __init__(self, docindex, **kwargs)
    Construct a new HTML writer, using the given documentation index.
    source code
    call graph 
    string
    _find_top_page(self, pagename)
    Find the top page for the API documentation.
    source code
    call graph 
        1. Interface Methods
    None
    write(self, directory=None)
    Write the documentation to the given directory.
    source code
    call graph 
     
    _write(self, write_func, directory, filename, *args) source code
    call graph 
    None
    _mkdir(self, directory)
    If the given directory does not exist, then attempt to create it.
    source code
    call graph 
        2.1. Module Pages
     
    write_module(self, out, doc)
    Write an HTML page containing the API documentation for the given module to out.
    source code
    call graph 
        2.??. Source Code Pages
     
    write_sourcecode(self, out, doc, name_to_docs) source code
    call graph 
        2.2. Class Pages
     
    write_class(self, out, doc)
    Write an HTML page containing the API documentation for the given class to out.
    source code
    call graph 
     
    write_class_tree_graph(self, out, doc, graphmaker)
    Write HTML code for a class tree graph of doc (a classdoc), using graphmaker to draw the actual graph.
    source code
    call graph 
        2.3. Trees pages
     
    write_module_tree(self, out) source code
    call graph 
     
    write_class_tree(self, out)
    Write HTML code for a nested list showing the base/subclass relationships between all documented classes.
    source code
    call graph 
     
    write_treepage_header(self, out, title, url) source code
    call graph 
        2.4. Index pages
     
    write_link_index(self, out, indices, title, url, index_by_section, sections='ABCDEFGHIJKLMNOPQRSTUVWXYZ_', section_url='#%s') source code
    call graph 
     
    write_metadata_index(self, out, indices, field, title, typ)
    Write an HTML page containing a metadata index.
    source code
    call graph 
     
    write_indexpage_header(self, out, indices, title, url)
    A helper for the index page generation functions, which generates a header that can be used to navigate between the different indices.
    source code
    call graph 
     
    write_index_section(self, out, items, add_blankline=False) source code
    call graph 
        2.5. Help Page
     
    write_help(self, out)
    Write an HTML help file to the given stream.
    source code
    call graph 
        2.6. Frames-based Table of Contents
     
    write_frames_index(self, out)
    Write the frames index file for the frames-based table of contents to the given streams.
    source code
     
    write_toc(self, out) source code
     
    write_toc_section(self, out, name, docs, fullname=True) source code
    call graph 
     
    write_project_toc(self, out) source code
    call graph 
     
    write_module_toc(self, out, doc)
    Write an HTML page containing the table of contents page for the given module to the given streams.
    source code
    call graph 
        2.7. Project homepage (index.html)
     
    write_homepage(self, directory)
    Write an index.html file in the given directory.
    source code
    call graph 
     
    write_redirect_index(self, out, top, name) source code
        2.8. Stylesheet (epydoc.css)
    None
    write_css(self, directory, cssname)
    Write the CSS stylesheet in the given directory.
    source code
    call graph 
        2.9. Javascript (epydoc.js)
     
    write_javascript(self, directory) source code
    call graph 
        2.10. Graphs
     
    render_graph(self, graph) source code
    call graph 
    str
    render_callgraph(self, callgraph, token='')
    Render the HTML chunk of a callgraph.
    source code
    str
    callgraph_link(self, callgraph, token='')
    Render the HTML chunk of a callgraph link.
    source code
        2.11. Images
     
    write_images(self, directory) source code
    call graph 
        3.1. Page Header
     
    write_header(self, out, title)
    Generate HTML code for the standard page header, and write it to out.
    source code
        3.2. Page Footer
     
    write_footer(self, out, short=False)
    Generate HTML code for the standard page footer, and write it to out.
    source code
        3.3. Navigation Bar
     
    write_navbar(self, out, context)
    Generate HTML code for the navigation bar, and write it to out.
    source code
        3.4. Breadcrumbs
     
    write_breadcrumbs(self, out, context, context_url)
    Generate HTML for the breadcrumbs line, and write it to out.
    source code
     
    breadcrumbs(self, doc) source code
    call graph 
     
    _crumb(self, doc) source code
    call graph 
        3.5. Summary Tables
     
    write_summary_table(self, out, heading, doc, value_type)
    Generate HTML code for a summary table, and write it to out.
    source code
    call graph 
     
    write_summary_group(self, out, doc, name, var_docs, grouped_inh_vars) source code
    call graph 
     
    write_inheritance_list(self, out, doc, listed_inh_vars) source code
    call graph 
     
    write_var_list(self, out, vardocs) source code
    call graph 
     
    write_summary_line(self, out, var_doc, container)
    Generate HTML code for a single line of a summary table, and write it to out.
    source code
    call graph 
     
    _write_summary_line(self, out, typ, description, tr_class, pysrc_link, callgraph) source code
        3.6. Details Lists
     
    write_details_list(self, out, heading, doc, value_type) source code
    call graph 
     
    write_details_entry(self, out, var_doc) source code
    call graph 
     
    labelled_list_item(self, lhs, rhs) source code
     
    property_accessor_to_html(self, val_doc, context=None) source code
    call graph 
     
    arg_name_to_html(self, func_doc, arg_name)
    A helper function used to format an argument name, for use in the argument description list under a routine's details entry.
    source code
    call graph 
     
    write_function_details_entry(self, out, var_doc, descr, callgraph, rtype, rdescr, arg_descrs, div_class) source code
     
    write_property_details_entry(self, out, var_doc, descr, accessors, div_class) source code
     
    write_variable_details_entry(self, out, var_doc, descr, div_class) source code
     
    variable_tooltip(self, var_doc) source code
    call graph 
     
    pprint_value(self, val_doc) source code
    call graph 
        Base Tree
    string
    base_tree(self, doc, width=None, postfix='', context=None)
    Returns: The HTML code for a class's base tree.
    source code
    int
    find_tree_width(self, doc, context)
    Helper function for base_tree.
    source code
     
    contextual_label(self, doc, context)
    Return the label for doc to be shown in context.
    source code
        Function Signatures
    str
    function_signature(self, api_doc, is_summary=False, link_name=False, anchor=False, context=None)
    Render a function signature in HTML.
    source code
    call graph 
    str
    summary_name(self, api_doc, css_class='summary-name', link_name=False, anchor=False)
    Render an object name in HTML.
    source code
    call graph 
     
    func_arg(self, name, default, css_class) source code
    call graph 
     
    _arg_name(self, arg) source code
    call graph 
        Import Lists
     
    write_imports(self, out, doc) source code
     
    _import(self, var_doc, context) source code
        Module Trees
     
    write_module_list(self, out, doc) source code
    call graph 
     
    write_module_tree_item(self, out, doc, package=None) source code
    call graph 
        Class trees
     
    write_class_tree_item(self, out, doc, class_set) source code
        Standard Fields
     
    write_standard_fields(self, out, doc)
    Write HTML code containing descriptions of any standard markup fields that are defined by the given APIDoc object (such as @author and @todo fields).
    source code
    call graph 
     
    write_standard_field(self, out, doc, field, descrs, arg='') source code
        Index generation
     
    build_identifier_index(self) source code
    call graph 
     
    _group_by_letter(self, items)
    Preserves sort order of the input.
    source code
    call graph 
     
    build_term_index(self) source code
    call graph 
     
    _terms_from_docstring(self, base_url, container, parsed_docstring) source code
    call graph 
     
    build_metadata_index(self, field_name) source code
    call graph 
     
    _term_index_to_anchor(self, term)
    Given the name of an inline index item, construct a URI anchor.
    source code
    call graph 
        Redirect page
     
    write_redirect_page(self, out)
    Build the auto-redirect page, which translates dotted names to URLs using javascript.
    source code
    call graph 
     
    _write_redirect_page(self, out, pages) source code
        URLs list
     
    write_api_list(self, out)
    Write a list of mapping name->url for all the documented objects.
    source code
    call graph 
     
    write_url_record(self, out, obj) source code
    call graph 
        Helper functions
     
    _val_is_public(self, valdoc)
    Make a best-guess as to whether the given class is public.
    source code
    call graph 
     
    write_table_header(self, out, css_class, heading=None, private_link=True, colspan=2) source code
     
    write_group_header(self, out, group, tr_class='') source code
     
    url(self, obj)
    Return the URL for the given object, which can be a VariableDoc, a ValueDoc, or a DottedName.
    source code
    call graph 
     
    _url(self, obj)
    Internal helper for url.
    source code
    call graph 
     
    pysrc_link(self, api_doc) source code
    call graph 
     
    pysrc_url(self, api_doc) source code
    call graph 
     
    href(self, target, label=None, css_class=None, context=None, tooltip=None)
    Return the HTML code for an HREF link to the given target (which can be a VariableDoc, a ValueDoc, or a DottedName.
    source code
    call graph 
     
    _attr_to_html(self, attr, api_doc, indent) source code
    call graph 
     
    summary(self, api_doc, indent=0) source code
    call graph 
     
    descr(self, api_doc, indent=0) source code
    call graph 
     
    type_descr(self, api_doc, indent=0) source code
    call graph 
     
    return_type(self, api_doc, indent=0) source code
    call graph 
     
    return_descr(self, api_doc, indent=0) source code
    call graph 
     
    docstring_to_html(self, parsed_docstring, where=None, indent=0) source code
    call graph 
     
    description(self, parsed_docstring, where=None, indent=0) source code
    call graph 
     
    doc_kind(self, doc) source code
    call graph 
     
    _doc_or_ancestor_is_private(self, api_doc) source code
    call graph 
     
    _private_subclasses(self, class_doc)
    Return a list of all subclasses of the given class that are private, as determined by _val_is_private.
    source code
    call graph 
    Class Variables [hide private]
        2.4. Index pages
      SPLIT_IDENT_INDEX_SIZE = 3000
    If the identifier index has more than this number of entries, then it will be split into separate pages, one for each alphabetical section.
      LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'
    The alphabetical sections that are used for link index pages.
        2.9. Javascript (epydoc.js)
      TOGGLE_PRIVATE_JS = 'function toggle_private() {\n // S...
    A javascript that is used to show or hide the API documentation for private objects.
      GET_COOKIE_JS = 'function getCookie(name) {\n var dc = ...
    A javascript that is used to read the value of a cookie.
      SET_FRAME_JS = 'function setFrame(url1, url2) {\n par...
    A javascript that is used to set the contents of two frames at once.
      HIDE_PRIVATE_JS = 'function checkCookie() {\n var cmd=g...
    A javascript that is used to hide private variables, unless either: (a) the cookie says not to; or (b) we appear to be linking to a private variable.
      TOGGLE_CALLGRAPH_JS = 'function toggleCallGraph(id) {\n ...
      SHOW_PRIVATE_JS = 'function show_private() {\n var elts...
      GET_ANCHOR_JS = 'function get_anchor() {\n var href =...
      REDIRECT_URL_JS = 'function redirect_url(dottedName) {\n ...
    A javascript that is used to implement the auto-redirect page.
        2.10. Graphs
      RE_CALLGRAPH_ID = re.compile(r'["\'](.+-div)[\'"]')
        2.11. Images
      IMAGES = {'crarr.png': 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAMAAA...
        3.6. Details Lists
      SPECIAL_METHODS = {'__add__': 'Addition operator', '__and__': ...
        Index generation
      METADATA_INDICES = [('bug', 'Bug List', 'Bugs'), ('todo', 'To ...
    A list of metadata indices that should be generated.
        Helper functions
      TABLE_FOOTER = '</table>\n'
      PRIVATE_LINK = '<span class="options">[<a href="javascript:voi...
      _url_cache = {1078260780: 'epydoc-module.html', 1078260940: 'e...
    Instance Variables [hide private]
      _show_private
    Should private docs be included?
      _prj_name
    The project's name (for the project link in the navbar)
      _prj_url
    URL for the project link in the navbar
      _prj_link
    HTML code for the project link in the navbar
      _top_page
    The 'main' page
      _css
    CSS stylesheet to use
      _helpfile
    Filename of file to extract help contents from
      _frames_index
    Should a frames index be created?
      _show_imports
    Should imports be listed?
      _propfunc_linelen
    [XXX] Not used!
      _variable_maxlines
    Max lines for variable values
      _variable_linelen
    Max line length for variable values
      _variable_summary_linelen
    Max length for variable value summaries
      _variable_tooltip_linelen
    Max length for variable tooltips
      _inheritance
    How should inheritance be displayed? 'listed', 'included', or 'grouped'
      _incl_sourcecode
    Should pages be generated for source code of modules?
      _mark_docstrings
    Wrap <span class='docstring'>...</span> around docstrings?
      _graph_types
    Graphs that we should include in our output.
      _include_log
    Are we generating an HTML log page?
      _src_code_tab_width
    Number of spaces to replace each tab with in source code listings.
      _callgraph_cache
    Map the callgraph uid to their HTML representation.
      _redundant_details
    If true, then include objects in the details list even if all info about them is already provided by the summary table.
      module_list
    The list of ModuleDocs for the documented modules.
      module_set
    The set of ModuleDocs for the documented modules.
      class_list
    The list of ClassDocs for the documented classes.
      class_set
    The set of ClassDocs for the documented classes.
      routine_list
    The list of RoutineDocs for the documented routines.
      indexed_docs
    The list of APIDocs for variables and values that should be included in the index.
    Method Details [hide private]

    __init__(self, docindex, **kwargs)
    (Constructor)

    source code 
    call graph 

    Construct a new HTML writer, using the given documentation index.

    Parameters:
    • docindex - The documentation index.
    • prj_name (string) - The name of the project. Defaults to none.
    • prj_url (string) - The target for the project hopeage link on the navigation bar. If prj_url is not specified, then no hyperlink is created.
    • prj_link (string) - The label for the project link on the navigation bar. This link can contain arbitrary HTML code (e.g. images). By default, a label is constructed from prj_name.
    • top_page (string) - The top page for the documentation. This is the default page shown main frame, when frames are enabled. top can be a URL, the name of a module, the name of a class, or one of the special strings "trees.html", "indices.html", or "help.html". By default, the top-level package or module is used, if there is one; otherwise, "trees" is used.
    • css (string) - The CSS stylesheet file. If css is a file name, then the specified file's conents will be used. Otherwise, if css is the name of a CSS stylesheet in epydoc.docwriter.html_css, then that stylesheet will be used. Otherwise, an error is reported. If no stylesheet is specified, then the default stylesheet is used.
    • help_file (string) - The name of the help file. If no help file is specified, then the default help file will be used.
    • show_private (boolean) - Whether to create documentation for private objects. By default, private objects are documented.
    • show_frames (boolean)) - Whether to create a frames-based table of contents. By default, it is produced.
    • show_imports (boolean) - Whether or not to display lists of imported functions and classes. By default, they are not shown.
    • variable_maxlines (int) - The maximum number of lines that should be displayed for the value of a variable in the variable details section. By default, 8 lines are displayed.
    • variable_linelength (int) - The maximum line length used for displaying the values of variables in the variable details sections. If a line is longer than this length, then it will be wrapped to the next line. The default line length is 70 characters.
    • variable_summary_linelength (int) - The maximum line length used for displaying the values of variables in the summary section. If a line is longer than this length, then it will be truncated. The default is 40 characters.
    • variable_tooltip_linelength (int) - The maximum line length used for tooltips for the values of variables. If a line is longer than this length, then it will be truncated. The default is 600 characters.
    • property_function_linelength (int) - The maximum line length used to dispaly property functions (fget, fset, and fdel) that contain something other than a function object. The default length is 40 characters.
    • inheritance (string) - How inherited objects should be displayed. If inheritance='grouped', then inherited objects are gathered into groups; if inheritance='listed', then inherited objects are listed in a short list at the end of their group; if inheritance='included', then inherited objects are mixed in with non-inherited objects. The default is 'grouped'.
    • include_source_code (boolean) - If true, then generate colorized source code files for each python module.
    • include_log (boolean) - If true, the the footer will include an href to the page 'epydoc-log.html'.
    • src_code_tab_width (int) - Number of spaces to replace each tab with in source code listings.

    _find_top_page(self, pagename)

    source code 
    call graph 

    Find the top page for the API documentation. This page is used as the default page shown in the main frame, when frames are used. When frames are not used, this page is copied to index.html.

    Parameters:
    • pagename (string) - The name of the page, as specified by the keyword argument top to the constructor.
    Returns: string
    The URL of the top page.

    write(self, directory=None)

    source code 
    call graph 

    Write the documentation to the given directory.

    Parameters:
    • directory (string) - The directory to which output should be written. If no directory is specified, output will be written to the current directory. If the directory does not exist, it will be created.
    Returns: None
    Raises:
    • OSError - If directory cannot be created.
    • OSError - If any file cannot be created or written to.

    write_module(self, out, doc)

    source code 
    call graph 

    Write an HTML page containing the API documentation for the given module to out.

    Parameters:
    • doc - A ModuleDoc containing the API documentation for the module that should be described.

    write_class(self, out, doc)

    source code 
    call graph 

    Write an HTML page containing the API documentation for the given class to out.

    Parameters:
    • doc - A ClassDoc containing the API documentation for the class that should be described.

    write_class_tree_graph(self, out, doc, graphmaker)

    source code 
    call graph 

    Write HTML code for a class tree graph of doc (a classdoc), using graphmaker to draw the actual graph. graphmaker should be class_tree_graph(), or uml_class_tree_graph(), or any other function with a compatible signature.

    If the given class has any private sublcasses (including recursive subclasses), then two graph images will be generated -- one to display when private values are shown, and the other to display when private values are hidden.

    write_class_tree(self, out)

    source code 
    call graph 

    Write HTML code for a nested list showing the base/subclass relationships between all documented classes. Each element of the top-level list is a class with no (documented) bases; and under each class is listed all of its subclasses. Note that in the case of multiple inheritance, a class may appear multiple times.

    To Do: For multiple inheritance, don't repeat subclasses the second time a class is mentioned; instead, link to the first mention.

    write_help(self, out)

    source code 
    call graph 

    Write an HTML help file to the given stream. If self._helpfile contains a help file, then use it; otherwise, use the default helpfile from epydoc.docwriter.html_help.

    write_module_toc(self, out, doc)

    source code 
    call graph 

    Write an HTML page containing the table of contents page for the given module to the given streams. This page lists the modules, classes, exceptions, functions, and variables defined by the module.

    write_homepage(self, directory)

    source code 
    call graph 

    Write an index.html file in the given directory. The contents of this file are copied or linked from an existing page, so this method must be called after all pages have been written. The page used is determined by _frames_index and _top_page:

    write_css(self, directory, cssname)

    source code 
    call graph 

    Write the CSS stylesheet in the given directory. If cssname contains a stylesheet file or name (from epydoc.docwriter.html_css), then use that stylesheet; otherwise, use the default stylesheet.

    Returns: None

    render_callgraph(self, callgraph, token='')

    source code 

    Render the HTML chunk of a callgraph.

    If callgraph is a string, use the _callgraph_cache to return a pre-rendered HTML chunk. This mostly avoids to run dot twice for the same callgraph. Else, run the graph and store its HTML output in the cache.

    Parameters:
    • callgraph (DotGraph or str) - The graph to render or its uid.
    • token (str) - A string that can be used to make the <div> id unambiguous, if the callgraph is used more than once in a page.
    Returns: str
    The HTML representation of the graph.

    callgraph_link(self, callgraph, token='')

    source code 

    Render the HTML chunk of a callgraph link.

    The link can toggles the visibility of the callgraph rendered using render_callgraph with matching parameters.

    Parameters:
    • callgraph (DotGraph or str) - The graph to render or its uid.
    • token (str) - A string that can be used to make the <div> id unambiguous, if the callgraph is used more than once in a page.
    Returns: str
    The HTML representation of the graph link.

    write_header(self, out, title)

    source code 

    Generate HTML code for the standard page header, and write it to out. title is a string containing the page title. It should be appropriately escaped/encoded.

    write_navbar(self, out, context)

    source code 

    Generate HTML code for the navigation bar, and write it to out. The navigation bar typically looks like:

        [ Home Trees Index Help             Project ]
    
    Parameters:
    • context - A value indicating what page we're generating a navigation bar for. If we're generating an API documentation page for an object, then context is a ValueDoc containing the documentation for that object; otherwise, context is a string name for the page. The following string names are recognized: 'tree', 'index', and 'help'.

    write_breadcrumbs(self, out, context, context_url)

    source code 

    Generate HTML for the breadcrumbs line, and write it to out. The breadcrumbs line is an invisible table with a list of pointers to the current object's ancestors on the left; and the show/hide private selector and the frames/noframes selector on the right.

    Parameters:
    • context (ValueDoc) - The API documentation for the object whose breadcrumbs we should generate.

    write_summary_table(self, out, heading, doc, value_type)

    source code 
    call graph 

    Generate HTML code for a summary table, and write it to out. A summary table is a table that includes a one-row description for each variable (of a given type) in a module or class.

    Parameters:
    • heading - The heading for the summary table; typically, this indicates what kind of value the table describes (e.g., functions or classes).
    • doc - A ValueDoc object containing the API documentation for the module or class whose variables we should summarize.
    • value_type - A string indicating what type of value should be listed in this summary table. This value is passed on to doc's select_variables() method.

    write_summary_line(self, out, var_doc, container)

    source code 
    call graph 

    Generate HTML code for a single line of a summary table, and write it to out. See write_summary_table for more information.

    Parameters:
    • var_doc - The API documentation for the variable that should be described by this line of the summary table.
    • container - The API documentation for the class or module whose summary table we're writing.

    arg_name_to_html(self, func_doc, arg_name)

    source code 
    call graph 

    A helper function used to format an argument name, for use in the argument description list under a routine's details entry. This just wraps strong & code tags around the arg name; and if the arg name is associated with a type, then adds it parenthetically after the name.

    base_tree(self, doc, width=None, postfix='', context=None)

    source code 
    Returns: string
    The HTML code for a class's base tree. The tree is drawn 'upside-down' and right justified, to allow for multiple inheritance.

    find_tree_width(self, doc, context)

    source code 

    Helper function for base_tree.

    Returns: int
    The width of a base tree, when drawn right-justified. This is used by base_tree to determine how far to indent lines of the base tree.

    function_signature(self, api_doc, is_summary=False, link_name=False, anchor=False, context=None)

    source code 
    call graph 

    Render a function signature in HTML.

    Parameters:
    • api_doc (VariableDoc or RoutineDoc) - The object whose name is to be rendered. If a VariableDoc, its value should be a RoutineDoc
    • is_summary - True if the fuction is to be rendered in the summary. type css_class: bool
    • link_name (bool) - If True, the name is a link to the object anchor.
    • anchor (bool) - If True, the name is the object anchor.
    • context (DottedName) - If set, represent the function name from this context. Only useful when api_doc is a RoutineDoc.
    Returns: str
    The HTML code for the object.

    summary_name(self, api_doc, css_class='summary-name', link_name=False, anchor=False)

    source code 
    call graph 

    Render an object name in HTML.

    Parameters:
    • api_doc (APIDoc) - The object whose name is to be rendered
    • css_class - The CSS class to assign to the rendered name type css_class: str
    • link_name (bool) - If True, the name is a link to the object anchor.
    • anchor (bool) - If True, the name is the object anchor.
    Returns: str
    The HTML code for the object.

    write_standard_fields(self, out, doc)

    source code 
    call graph 

    Write HTML code containing descriptions of any standard markup fields that are defined by the given APIDoc object (such as @author and @todo fields).

    Parameters:
    • doc - The APIDoc object containing the API documentation for the object whose standard markup fields should be described.

    _term_index_to_anchor(self, term)

    source code 
    call graph 

    Given the name of an inline index item, construct a URI anchor. These anchors are used to create links from the index page to each index item.

    write_redirect_page(self, out)

    source code 
    call graph 

    Build the auto-redirect page, which translates dotted names to URLs using javascript. When the user visits <redirect.html#dotted.name>, they will automatically get redirected to the page for the object with the given fully-qualified dotted name. E.g., for epydoc, <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to <epydoc.apidoc-module.html#UNKNOWN>.

    href(self, target, label=None, css_class=None, context=None, tooltip=None)

    source code 
    call graph 

    Return the HTML code for an HREF link to the given target (which can be a VariableDoc, a ValueDoc, or a DottedName. If a NamespaceDoc context is specified, the target label is contextualized to it.

    _private_subclasses(self, class_doc)

    source code 
    call graph 

    Return a list of all subclasses of the given class that are private, as determined by _val_is_private. Recursive subclasses are included in this list.


    Class Variable Details [hide private]

    TOGGLE_PRIVATE_JS

    A javascript that is used to show or hide the API documentation for private objects. In order for this to work correctly, all documentation for private objects should be enclosed in <div class="private">...</div> elements.

    Value:
    '''function toggle_private() {
            // Search for any private/public links on this page.  Store
            // their old text in "cmd," so we will know what action to
            // take; and change their text to the opposite action.
            var cmd = "?";
            var elts = document.getElementsByTagName("a");
            for(var i=0; i<elts.length; i++) {
              if (elts[i].className == "privatelink") {
    ...
    

    GET_COOKIE_JS

    A javascript that is used to read the value of a cookie. This is used to remember whether private variables should be shown or hidden.

    Value:
    '''function getCookie(name) {
            var dc = document.cookie;
            var prefix = name + "=";
            var begin = dc.indexOf("; " + prefix);
            if (begin == -1) {
              begin = dc.indexOf(prefix);
              if (begin != 0) return null;
            } else
    ...
    

    SET_FRAME_JS

    A javascript that is used to set the contents of two frames at once. This is used by the project table-of-contents frame to set both the module table-of-contents frame and the main frame when the user clicks on a module.

    Value:
    '''function setFrame(url1, url2) {
              parent.frames[1].location.href = url1;
              parent.frames[2].location.href = url2;
          }'''
    

    HIDE_PRIVATE_JS

    A javascript that is used to hide private variables, unless either: (a) the cookie says not to; or (b) we appear to be linking to a private variable.

    Value:
    '''function checkCookie() {
            var cmd=getCookie("EpydocPrivate");
            if (cmd && cmd.substr(0,4)!="show" && location.href.indexOf("#\
    _") < 0)
                toggle_private();
          }'''
    

    TOGGLE_CALLGRAPH_JS

    Value:
    '''function toggleCallGraph(id) {
            var elt = document.getElementById(id);
            if (elt.style.display == "none")
                elt.style.display = "block";
            else
                elt.style.display = "none";
          }'''
    

    SHOW_PRIVATE_JS

    Value:
    '''function show_private() {
            var elts = document.getElementsByTagName("a");
            for(var i=0; i<elts.length; i++) {
              if (elts[i].className == "privatelink") {
                cmd = elts[i].innerHTML;
                if (cmd && cmd.substr(0,4)=="show")
                    toggle_private();
              }
    ...
    

    GET_ANCHOR_JS

    Value:
    '''function get_anchor() {
              var href = location.href;
              var start = href.indexOf("#")+1;
              if ((start != 0) && (start != href.length))
                  return href.substring(start, href.length);
          }'''
    

    REDIRECT_URL_JS

    A javascript that is used to implement the auto-redirect page. When the user visits <redirect.html#dotted.name>, they will automatically get redirected to the page for the object with the given fully-qualified dotted name. E.g., for epydoc, <redirect.html#epydoc.apidoc.UNKNOWN> redirects the user to <epydoc.apidoc-module.html#UNKNOWN>.

    Value:
    '''function redirect_url(dottedName) {
              // Scan through each element of the "pages" list, and check
              // if "name" matches with any of them.
              for (var i=0; i<pages.length; i++) {
    
                  // Each page has the form "<pagename>-m" or "<pagename>-\
    c";
                  // extract the <pagename> portion & compare it to dotted\
    ...
    

    IMAGES

    Value:
    {'crarr.png': '''iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAMAAABlokWQAAAALHRFW\
    HRDcmVhdGlvbiBUaW1lAFR1
    ZSAyMiBBdWcgMjAwNiAwMDo0MzoxMCAtMDUwMGAMEFgAAAAHdElNRQfWCBYFASkQ033WAA\
    AACXBI
    WXMAAB7CAAAewgFu0HU+AAAABGdBTUEAALGPC/xhBQAAAEVQTFRF////zcOw18/AgGY0c1\
    cg4dvQ
    inJEYEAAYkME3NXI6eTcloFYe2Asr5+AbE4Uh29A9fPwqpl4ZEUI8O3onopk0Ma0lH5U1n\
    fFdgAA
    ...
    

    SPECIAL_METHODS

    Value:
    {'__add__': 'Addition operator',
     '__and__': 'And operator',
     '__call__': 'Call operator',
     '__cmp__': 'Comparison operator',
     '__contains__': 'In operator',
     '__del__': 'Destructor',
     '__delitem__': 'Index deletion operator',
     '__delslice__': 'Slice deletion operator',
    ...
    

    METADATA_INDICES

    A list of metadata indices that should be generated. Each entry in this list is a tuple (tag, label, short_label), where tag is the cannonical tag of a metadata field; label is a label for the index page; and short_label is a shorter label, used in the index selector.

    Value:
    [('bug', 'Bug List', 'Bugs'),
     ('todo', 'To Do List', 'To Do'),
     ('change', 'Change Log', 'Changes'),
     ('deprecated', 'Deprecation List', 'Deprecations'),
     ('since', 'Introductions List', 'Introductions')]
    

    PRIVATE_LINK

    Value:
    '''<span class="options">[<a href="javascript:void(0);" class="private\
    link"
        onclick="toggle_private();">hide&nbsp;private</a>]</span>'''
    

    _url_cache

    Value:
    {1078260780: 'epydoc-module.html',
     1078260940: 'epydoc-module.html',
     1078261708: 'epydoc-module.html#DEBUG',
     1078261804: 'epydoc-module.html#__author__',
     1078261868: 'epydoc-module.html#__license__',
     1078261932: 'epydoc-module.html#__url__',
     1078261996: 'epydoc-module.html#__version__',
     1078262028: 'epydoc.compat-module.html',
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.log.Logger-class.html0000644000175000017500000006157510750103050022772 0ustar pronovicpronovic epydoc.log.Logger
    Package epydoc :: Module log :: Class Logger
    [hide private]
    [frames] | no frames]

    Class Logger

    source code


    An abstract base class that defines the interface for loggers, which are used by epydoc to report information back to the user. Loggers are responsible for tracking two types of information:

    • Messages, such as warnings and errors.
    • Progress on the current task.

    This abstract class allows the command-line interface and the graphical interface to each present this information to the user in the way that's most natural for each interface. To set up a logger, create a subclass of Logger that overrides all methods, and register it using register_logger.

    Instance Methods [hide private]
     
    log(self, level, message)
    Display a message.
    source code
     
    close(self)
    Perform any tasks needed to close this logger.
    source code
     
    start_block(self, header)
    Start a new message block.
    source code
     
    end_block(self)
    End a warning block.
    source code
     
    start_progress(self, header=None)
    Begin displaying progress for a new task.
    source code
    call graph 
     
    end_progress(self)
    Finish off the display of progress for the current task.
    source code
    call graph 
     
    progress(self, percent, message='')
    Update the progress display.
    source code
    call graph 
    Method Details [hide private]

    log(self, level, message)

    source code 

    Display a message.

    Parameters:
    • message - The message string to display. message may contain newlines, but does not need to end in a newline.
    • level - An integer value indicating the severity of the message.

    start_block(self, header)

    source code 

    Start a new message block. Any calls to info(), warning(), or error() that occur between a call to start_block and a corresponding call to end_block will be grouped together, and displayed with a common header. start_block can be called multiple times (to form nested blocks), but every call to start_block must be balanced by a call to end_block.

    end_block(self)

    source code 

    End a warning block. See start_block for details.

    start_progress(self, header=None)

    source code 
    call graph 

    Begin displaying progress for a new task. header is a description of the task for which progress is being reported. Each call to start_progress must be followed by a call to end_progress (with no intervening calls to start_progress).

    end_progress(self)

    source code 
    call graph 

    Finish off the display of progress for the current task. See start_progress for more information.

    progress(self, percent, message='')

    source code 
    call graph 

    Update the progress display.

    Parameters:
    • percent - A float from 0.0 to 1.0, indicating how much progress has been made.
    • message - A message indicating the most recent action that contributed towards that progress.

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest.HTMLDoctestColorizer-class.html0000644000175000017500000004702110750103050027706 0ustar pronovicpronovic epydoc.markup.doctest.HTMLDoctestColorizer
    Package epydoc :: Package markup :: Module doctest :: Class HTMLDoctestColorizer
    [hide private]
    [frames] | no frames]

    Class HTMLDoctestColorizer

    source code


    A subclass of DoctestColorizer that generates HTML output.

    Instance Methods [hide private]
     
    markup(self, s, tag)
    Apply syntax highlighting to a single substring from a doctest block.
    source code
    call graph 

    Inherited from DoctestColorizer: colorize_codeblock, colorize_doctest, colorize_inline, subfunc

    Class Variables [hide private]
      PREFIX = '<pre class="py-doctest">\n'
    A string that is added to the beginning of the strings returned by colorize_codeblock and colorize_doctest.
      SUFFIX = '</pre>\n'
    A string that is added to the end of the strings returned by colorize_codeblock and colorize_doctest.

    Inherited from DoctestColorizer: DOCTEST_DIRECTIVE_RE, DOCTEST_EXAMPLE_RE, DOCTEST_RE, EXCEPT_RE, PROMPT2_RE, PROMPT_RE

    Method Details [hide private]

    markup(self, s, tag)

    source code 
    call graph 

    Apply syntax highlighting to a single substring from a doctest block. s is the substring, and tag is the tag that should be applied to the substring. tag will be one of the following strings:

    • prompt -- the Python PS1 prompt (>>>)
    • more -- the Python PS2 prompt (...)
    • keyword -- a Python keyword (for, if, etc.)
    • builtin -- a Python builtin name (abs, dir, etc.)
    • string -- a string literal
    • comment -- a comment
    • except -- an exception traceback (up to the next >>>)
    • output -- the output from a doctest block.
    • defname -- the name of a function or class defined by a def or class statement.
    • other -- anything else (does *not* include output.)
    Overrides: DoctestColorizer.markup
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/bug-index.html0000644000175000017500000001245010750103050020254 0ustar pronovicpronovic Bug List
     
    [hide private]
    [frames] | no frames]
    [ Identifiers | Term Definitions | Bugs | To Do ]

    Bug List



    epydoc-3.0.1+dfsg/doc/api/epydoc.checker.DocChecker-class.html0000644000175000017500000010033310750103050024352 0ustar pronovicpronovic epydoc.checker.DocChecker
    Package epydoc :: Module checker :: Class DocChecker
    [hide private]
    [frames] | no frames]

    Class DocChecker

    source code

    Documentation completeness checker. DocChecker can be used to check that specified classes of objects are documented. To check the documentation for a group of objects, you should create a DocChecker from a DocIndex that documents those objects; and then use the check method to run specified checks on the objects' documentation.

    What checks are run, and what objects they are run on, are specified by the constants defined by DocChecker. These constants are divided into three groups.

    The check method is used to perform a check on the documentation. Its parameter is formed by or-ing together at least one value from each specifier group:

    >>> checker.check(DocChecker.MODULE | DocChecker.DESCR)

    To specify multiple values from a single group, simply or their values together:

    >>> checker.check(DocChecker.MODULE | DocChecker.CLASS |
    ...               DocChecker.FUNC )
    Instance Methods [hide private]
     
    __init__(self, docindex)
    Create a new DocChecker that can be used to run checks on the documentation of the objects documented by docindex
    source code
    boolean
    check(self, *check_sets)
    Run the specified checks on the documentation of the objects contained by this DocChecker's DocIndex.
    source code
     
    _check(self, checks) source code
     
    _name(self, doc) source code
    None
    _check_basic(self, doc)
    Check the description, author, version, and see-also fields of doc.
    source code
    None
    _check_module(self, doc)
    Run checks on the module whose APIDoc is doc.
    source code
    None
    _check_class(self, doc)
    Run checks on the class whose APIDoc is doc.
    source code
     
    _check_property(self, doc) source code
    None
    _check_var(self, doc)
    Run checks on the variable whose documentation is var and whose name is name.
    source code
    None
    _check_func(self, doc)
    Run checks on the function whose APIDoc is doc.
    source code
     
    warning(self, msg, doc) source code
    Class Variables [hide private]
      PROPERTY = 256
      ALL = 24831
        Types
    int MODULE = 1
    Type specifier that indicates that the documentation of modules should be checked.
    int CLASS = 2
    Type specifier that indicates that the documentation of classes should be checked.
    int FUNC = 4
    Type specifier that indicates that the documentation of functions should be checked.
    int VAR = 8
    Type specifier that indicates that the documentation of module variables should be checked.
    int PARAM = 64
    Type specifier that indicates that the documentation of function and method parameters should be checked.
    int RETURN = 128
    Type specifier that indicates that the documentation of return values should be checked.
    int ALL_T = 511
    Type specifier that indicates that the documentation of all objects should be checked.
    int CVAR
    Type specifier that indicates that the documentation of class variables should be checked.
    int IVAR
    Type specifier that indicates that the documentation of instance variables should be checked.
        Checks
    int TYPE = 256
    Check specifier that indicates that every variable and parameter should have a @type field.
    int AUTHOR = 1024
    Check specifier that indicates that every object should have an author field.
    int VERSION = 2048
    Check specifier that indicates that every object should have a version field.
    int DESCR = 4096
    Check specifier that indicates that every object should have a description.
    int ALL_C = 7936
    Check specifier that indicates that all checks should be run.
        Publicity
    int PRIVATE = 16384
    Specifier that indicates that private objects should be checked.
    Method Details [hide private]

    __init__(self, docindex)
    (Constructor)

    source code 

    Create a new DocChecker that can be used to run checks on the documentation of the objects documented by docindex

    Parameters:
    • docindex (Docindex) - A documentation map containing the documentation for the objects to be checked.

    check(self, *check_sets)

    source code 

    Run the specified checks on the documentation of the objects contained by this DocChecker's DocIndex. Any errors found are printed to standard out.

    Parameters:
    • check_sets (int) - The checks that should be run on the documentation. This value is constructed by or-ing together the specifiers that indicate which objects should be checked, and which checks should be run. See the module description for more information. If no checks are specified, then a default set of checks will be run.
    Returns: boolean
    True if no problems were found.

    _check_basic(self, doc)

    source code 

    Check the description, author, version, and see-also fields of doc. This is used as a helper function by _check_module, _check_class, and _check_func.

    Parameters:
    • doc (APIDoc) - The documentation that should be checked.
    Returns: None

    _check_module(self, doc)

    source code 

    Run checks on the module whose APIDoc is doc.

    Parameters:
    • doc (APIDoc) - The APIDoc of the module to check.
    Returns: None

    _check_class(self, doc)

    source code 

    Run checks on the class whose APIDoc is doc.

    Parameters:
    • doc (APIDoc) - The APIDoc of the class to check.
    Returns: None

    _check_var(self, doc)

    source code 

    Run checks on the variable whose documentation is var and whose name is name.

    Parameters:
    • doc (APIDoc) - The documentation for the variable to check.
    Returns: None

    _check_func(self, doc)

    source code 

    Run checks on the function whose APIDoc is doc.

    Parameters:
    • doc (APIDoc) - The APIDoc of the function to check.
    Returns: None

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.test-module.html0000644000175000017500000000224210750103050022677 0ustar pronovicpronovic test

    Module test


    Functions

    check_requirements
    main

    [hide private] epydoc-3.0.1+dfsg/doc/api/crarr.png0000644000175000017500000000052410750103050017322 0ustar pronovicpronovic‰PNG  IHDR e¢E,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIMEÖ)Ó}Ö pHYsÂÂnÐu>gAMA± üaEPLTEÿÿÿÍð×ÏÀ€f4sW áÛЊrD`@bCÜÕÈéäÜ–X{`,¯Ÿ€lN‡o@õóðª™xdEðí螊dÐÆ´”~TÖwÅvtRNS@æØfMIDATxÚc`@¼ì¼0&+š—Šˆ°»(’ˆ€ ;; /ðEXùØ‘?Ð n ƒª†— b;'ª+˜˜YÐ#œ(r<£"IEND®B`‚epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.ColorizingError-class.html0000644000175000017500000003632610750103050027117 0ustar pronovicpronovic epydoc.markup.epytext.ColorizingError
    Package epydoc :: Package markup :: Module epytext :: Class ColorizingError
    [hide private]
    [frames] | no frames]

    Class ColorizingError

    source code


    An error generated while colorizing a paragraph.

    Instance Methods [hide private]
     
    __init__(self, descr, token, charnum, is_fatal=1)
    Construct a new colorizing exception.
    source code
     
    descr(self) source code

    Inherited from ParseError: __cmp__, __repr__, __str__, is_fatal, linenum, set_linenum_offset

    Inherited from exceptions.Exception: __getitem__

    Class Variables [hide private]
      CONTEXT_RANGE = 20
    Instance Variables [hide private]

    Inherited from ParseError (private): _descr, _fatal, _linenum, _offset

    Method Details [hide private]

    __init__(self, descr, token, charnum, is_fatal=1)
    (Constructor)

    source code 

    Construct a new colorizing exception.

    Parameters:
    • descr (string) - A short description of the error.
    • token (Token) - The token where the error occured
    • charnum (int) - The character index of the position in token where the error occured.
    Overrides: exceptions.Exception.__init__

    descr(self)

    source code 
    Overrides: ParseError.descr

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.ParsedDocstring-class.html0000644000175000017500000010633410750103050025355 0ustar pronovicpronovic epydoc.markup.ParsedDocstring
    Package epydoc :: Package markup :: Class ParsedDocstring
    [hide private]
    [frames] | no frames]

    Class ParsedDocstring

    source code


    A standard intermediate representation for parsed docstrings that can be used to generate output. Parsed docstrings are produced by markup parsers (such as epytext.parse or javadoc.parse). ParsedDocstrings support several kinds of operation:

    The output generation methods (to_format()) use a DocstringLinker to link the docstring output with the rest of the documentation that epydoc generates.

    Subclassing

    The only method that a subclass is required to implement is to_plaintext(); but it is often useful to override the other methods. The default behavior of each method is described below:

    • to_format: Calls to_plaintext, and uses the string it returns to generate verbatim output.
    • summary: Returns self (i.e., the entire docstring).
    • split_fields: Returns (self, []) (i.e., extracts no fields).
    • index_terms: Returns [] (i.e., extracts no index terms).

    If and when epydoc adds more output formats, new to_format methods will be added to this base class; but they will always be given a default implementation.

    Instance Methods [hide private]
    (ParsedDocstring, list of Field)
    split_fields(self, errors=None)
    Split this docstring into its body and its fields.
    source code
    call graph 
    (ParsedDocstring, bool)
    summary(self)
    Returns: A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary.
    source code
     
    concatenate(self, other)
    Returns: A new parsed docstring containing the concatination of this docstring and other.
    source code
    call graph 
     
    __add__(self, other) source code
    call graph 
    string
    to_html(self, docstring_linker, **options)
    Translate this docstring to HTML.
    source code
    call graph 
    string
    to_latex(self, docstring_linker, **options)
    Translate this docstring to LaTeX.
    source code
    string
    to_plaintext(self, docstring_linker, **options)
    Translate this docstring to plaintext.
    source code
    list of ParsedDocstring
    index_terms(self)
    Returns: The list of index terms that are defined in this docstring.
    source code
    call graph 
    Method Details [hide private]

    split_fields(self, errors=None)

    source code 
    call graph 

    Split this docstring into its body and its fields.

    Parameters:
    • errors (list of ParseError) - A list where any errors generated during splitting will be stored. If no list is specified, then errors will be ignored.
    Returns: (ParsedDocstring, list of Field)
    A tuple (body, fields), where body is the main body of this docstring, and fields is a list of its fields. If the resulting body is empty, return None for the body.

    summary(self)

    source code 
    Returns: (ParsedDocstring, bool)
    A pair consisting of a short summary of this docstring and a boolean value indicating whether there is further documentation in addition to the summary. Typically, the summary consists of the first sentence of the docstring.

    concatenate(self, other)

    source code 
    call graph 
    Returns:
    A new parsed docstring containing the concatination of this docstring and other.
    Raises:
    • ValueError - If the two parsed docstrings are incompatible.

    to_html(self, docstring_linker, **options)

    source code 
    call graph 

    Translate this docstring to HTML.

    Parameters:
    • docstring_linker (DocstringLinker) - An HTML translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    An HTML fragment that encodes this docstring.

    to_latex(self, docstring_linker, **options)

    source code 

    Translate this docstring to LaTeX.

    Parameters:
    • docstring_linker (DocstringLinker) - A LaTeX translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A LaTeX fragment that encodes this docstring.

    to_plaintext(self, docstring_linker, **options)

    source code 

    Translate this docstring to plaintext.

    Parameters:
    • docstring_linker (DocstringLinker) - A plaintext translator for crossreference links into and out of the docstring.
    • options - Any extra options for the output. Unknown options are ignored.
    Returns: string
    A plaintext fragment that encodes this docstring.

    index_terms(self)

    source code 
    call graph 
    Returns: list of ParsedDocstring
    The list of index terms that are defined in this docstring. Each of these items will be added to the index page of the documentation.

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.xlink-pysrc.html0000644000175000017500000040331610750103050024145 0ustar pronovicpronovic epydoc.docwriter.xlink
    Package epydoc :: Package docwriter :: Module xlink
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.xlink

      1  """ 
      2  A Docutils_ interpreted text role for cross-API reference support. 
      3   
      4  This module allows a Docutils_ document to refer to elements defined in 
      5  external API documentation. It is possible to refer to many external API 
      6  from the same document. 
      7   
      8  Each API documentation is assigned a new interpreted text role: using such 
      9  interpreted text, an user can specify an object name inside an API 
     10  documentation. The system will convert such text into an url and generate a 
     11  reference to it. For example, if the API ``db`` is defined, being a database 
     12  package, then a certain method may be referred as:: 
     13   
     14      :db:`Connection.cursor()` 
     15   
     16  To define a new API, an *index file* must be provided. This file contains 
     17  a mapping from the object name to the URL part required to resolve such object. 
     18   
     19  Index file 
     20  ---------- 
     21   
     22  Each line in the the index file describes an object. 
     23   
     24  Each line contains the fully qualified name of the object and the URL at which 
     25  the documentation is located. The fields are separated by a ``<tab>`` 
     26  character. 
     27   
     28  The URL's in the file are relative from the documentation root: the system can 
     29  be configured to add a prefix in front of each returned URL. 
     30   
     31  Allowed names 
     32  ------------- 
     33   
     34  When a name is used in an API text role, it is split over any *separator*. 
     35  The separators defined are '``.``', '``::``', '``->``'. All the text from the 
     36  first noise char (neither a separator nor alphanumeric or '``_``') is 
     37  discarded. The same algorithm is applied when the index file is read. 
     38   
     39  First the sequence of name parts is looked for in the provided index file. 
     40  If no matching name is found, a partial match against the trailing part of the 
     41  names in the index is performed. If no object is found, or if the trailing part 
     42  of the name may refer to many objects, a warning is issued and no reference 
     43  is created. 
     44   
     45  Configuration 
     46  ------------- 
     47   
     48  This module provides the class `ApiLinkReader` a replacement for the Docutils 
     49  standalone reader. Such reader specifies the settings required for the 
     50  API canonical roles configuration. The same command line options are exposed by 
     51  Epydoc. 
     52   
     53  The script ``apirst2html.py`` is a frontend for the `ApiLinkReader` reader. 
     54   
     55  API Linking Options:: 
     56   
     57      --external-api=NAME 
     58                          Define a new API document.  A new interpreted text 
     59                          role NAME will be added. 
     60      --external-api-file=NAME:FILENAME 
     61                          Use records in FILENAME to resolve objects in the API 
     62                          named NAME. 
     63      --external-api-root=NAME:STRING 
     64                          Use STRING as prefix for the URL generated from the 
     65                          API NAME. 
     66   
     67  .. _Docutils: http://docutils.sourceforge.net/ 
     68  """ 
     69   
     70  # $Id: xlink.py 1586 2007-03-14 01:53:42Z dvarrazzo $ 
     71  __version__ = "$Revision: 1586 $"[11:-2] 
     72  __author__ = "Daniele Varrazzo" 
     73  __copyright__ = "Copyright (C) 2007 by Daniele Varrazzo" 
     74  __docformat__ = 'reStructuredText en' 
     75   
     76  import re 
     77  import sys 
     78  from optparse import OptionValueError 
     79   
     80  from epydoc import log 
     81   
    
    82 -class UrlGenerator:
    83 """ 84 Generate URL from an object name. 85 """
    86 - class IndexAmbiguous(IndexError):
    87 """ 88 The name looked for is ambiguous 89 """
    90
    91 - def get_url(self, name):
    92 """Look for a name and return the matching URL documentation. 93 94 First look for a fully qualified name. If not found, try with partial 95 name. 96 97 If no url exists for the given object, return `None`. 98 99 :Parameters: 100 `name` : `str` 101 the name to look for 102 103 :return: the URL that can be used to reach the `name` documentation. 104 `None` if no such URL exists. 105 :rtype: `str` 106 107 :Exceptions: 108 - `IndexError`: no object found with `name` 109 - `DocUrlGenerator.IndexAmbiguous` : more than one object found with 110 a non-fully qualified name; notice that this is an ``IndexError`` 111 subclass 112 """ 113 raise NotImplementedError
    114
    115 - def get_canonical_name(self, name):
    116 """ 117 Convert an object name into a canonical name. 118 119 the canonical name of an object is a tuple of strings containing its 120 name fragments, splitted on any allowed separator ('``.``', '``::``', 121 '``->``'). 122 123 Noise such parenthesis to indicate a function is discarded. 124 125 :Parameters: 126 `name` : `str` 127 an object name, such as ``os.path.prefix()`` or ``lib::foo::bar`` 128 129 :return: the fully qualified name such ``('os', 'path', 'prefix')`` and 130 ``('lib', 'foo', 'bar')`` 131 :rtype: `tuple` of `str` 132 """ 133 rv = [] 134 for m in self._SEP_RE.finditer(name): 135 groups = m.groups() 136 if groups[0] is not None: 137 rv.append(groups[0]) 138 elif groups[2] is not None: 139 break 140 141 return tuple(rv)
    142 143 _SEP_RE = re.compile(r"""(?x) 144 # Tokenize the input into keyword, separator, noise 145 ([a-zA-Z0-9_]+) | # A keyword is a alphanum word 146 ( \. | \:\: | \-\> ) | # These are the allowed separators 147 (.) # If it doesn't fit, it's noise. 148 # Matching a single noise char is enough, because it 149 # is used to break the tokenization as soon as some noise 150 # is found. 151 """)
    152 153
    154 -class VoidUrlGenerator(UrlGenerator):
    155 """ 156 Don't actually know any url, but don't report any error. 157 158 Useful if an index file is not available, but a document linking to it 159 is to be generated, and warnings are to be avoided. 160 161 Don't report any object as missing, Don't return any url anyway. 162 """
    163 - def get_url(self, name):
    164 return None
    165 166
    167 -class DocUrlGenerator(UrlGenerator):
    168 """ 169 Read a *documentation index* and generate URL's for it. 170 """
    171 - def __init__(self):
    172 self._exact_matches = {} 173 """ 174 A map from an object fully qualified name to its URL. 175 176 Values are both the name as tuple of fragments and as read from the 177 records (see `load_records()`), mostly to help `_partial_names` to 178 perform lookup for unambiguous names. 179 """ 180 181 self._partial_names= {} 182 """ 183 A map from partial names to the fully qualified names they may refer. 184 185 The keys are the possible left sub-tuples of fully qualified names, 186 the values are list of strings as provided by the index. 187 188 If the list for a given tuple contains a single item, the partial 189 match is not ambuguous. In this case the string can be looked up in 190 `_exact_matches`. 191 192 If the name fragment is ambiguous, a warning may be issued to the user. 193 The items can be used to provide an informative message to the user, 194 to help him qualifying the name in a unambiguous manner. 195 """ 196 197 self.prefix = '' 198 """ 199 Prefix portion for the URL's returned by `get_url()`. 200 """ 201 202 self._filename = None 203 """ 204 Not very important: only for logging. 205 """
    206
    207 - def get_url(self, name):
    208 cname = self.get_canonical_name(name) 209 url = self._exact_matches.get(cname, None) 210 if url is None: 211 212 # go for a partial match 213 vals = self._partial_names.get(cname) 214 if vals is None: 215 raise IndexError( 216 "no object named '%s' found" % (name)) 217 218 elif len(vals) == 1: 219 url = self._exact_matches[vals[0]] 220 221 else: 222 raise self.IndexAmbiguous( 223 "found %d objects that '%s' may refer to: %s" 224 % (len(vals), name, ", ".join(["'%s'" % n for n in vals]))) 225 226 return self.prefix + url
    227 228 #{ Content loading 229 # --------------- 230
    231 - def clear(self):
    232 """ 233 Clear the current class content. 234 """ 235 self._exact_matches.clear() 236 self._partial_names.clear()
    237
    238 - def load_index(self, f):
    239 """ 240 Read the content of an index file. 241 242 Populate the internal maps with the file content using `load_records()`. 243 244 :Parameters: 245 f : `str` or file 246 a file name or file-like object fron which read the index. 247 """ 248 self._filename = str(f) 249 250 if isinstance(f, basestring): 251 f = open(f) 252 253 self.load_records(self._iter_tuples(f))
    254
    255 - def _iter_tuples(self, f):
    256 """Iterate on a file returning 2-tuples.""" 257 for nrow, row in enumerate(f): 258 # skip blank lines 259 row = row.rstrip() 260 if not row: continue 261 262 rec = row.split('\t', 2) 263 if len(rec) == 2: 264 yield rec 265 else: 266 log.warning("invalid row in '%s' row %d: '%s'" 267 % (self._filename, nrow+1, row))
    268
    269 - def load_records(self, records):
    270 """ 271 Read a sequence of pairs name -> url and populate the internal maps. 272 273 :Parameters: 274 records : iterable 275 the sequence of pairs (*name*, *url*) to add to the maps. 276 """ 277 for name, url in records: 278 cname = self.get_canonical_name(name) 279 if not cname: 280 log.warning("invalid object name in '%s': '%s'" 281 % (self._filename, name)) 282 continue 283 284 # discard duplicates 285 if name in self._exact_matches: 286 continue 287 288 self._exact_matches[name] = url 289 self._exact_matches[cname] = url 290 291 # Link the different ambiguous fragments to the url 292 for i in range(1, len(cname)): 293 self._partial_names.setdefault(cname[i:], []).append(name)
    294 295 #{ API register 296 # ------------ 297 298 api_register = {} 299 """ 300 Mapping from the API name to the `UrlGenerator` to be used. 301 302 Use `register_api()` to add new generators to the register. 303 """ 304
    305 -def register_api(name, generator=None):
    306 """Register the API `name` into the `api_register`. 307 308 A registered API will be available to the markup as the interpreted text 309 role ``name``. 310 311 If a `generator` is not provided, register a `VoidUrlGenerator` instance: 312 in this case no warning will be issued for missing names, but no URL will 313 be generated and all the dotted names will simply be rendered as literals. 314 315 :Parameters: 316 `name` : `str` 317 the name of the generator to be registered 318 `generator` : `UrlGenerator` 319 the object to register to translate names into URLs. 320 """ 321 if generator is None: 322 generator = VoidUrlGenerator() 323 324 api_register[name] = generator
    325
    326 -def set_api_file(name, file):
    327 """Set an URL generator populated with data from `file`. 328 329 Use `file` to populate a new `DocUrlGenerator` instance and register it 330 as `name`. 331 332 :Parameters: 333 `name` : `str` 334 the name of the generator to be registered 335 `file` : `str` or file 336 the file to parse populate the URL generator 337 """ 338 generator = DocUrlGenerator() 339 generator.load_index(file) 340 register_api(name, generator)
    341
    342 -def set_api_root(name, prefix):
    343 """Set the root for the URLs returned by a registered URL generator. 344 345 :Parameters: 346 `name` : `str` 347 the name of the generator to be updated 348 `prefix` : `str` 349 the prefix for the generated URL's 350 351 :Exceptions: 352 - `IndexError`: `name` is not a registered generator 353 """ 354 api_register[name].prefix = prefix
    355 356 ###################################################################### 357 # Below this point requires docutils. 358 try: 359 import docutils 360 from docutils.parsers.rst import roles 361 from docutils import nodes, utils 362 from docutils.readers.standalone import Reader 363 except ImportError: 364 docutils = roles = nodes = utils = None
    365 - class Reader: settings_spec = ()
    366
    367 -def create_api_role(name, problematic):
    368 """ 369 Create and register a new role to create links for an API documentation. 370 371 Create a role called `name`, which will use the URL resolver registered as 372 ``name`` in `api_register` to create a link for an object. 373 374 :Parameters: 375 `name` : `str` 376 name of the role to create. 377 `problematic` : `bool` 378 if True, the registered role will create problematic nodes in 379 case of failed references. If False, a warning will be raised 380 anyway, but the output will appear as an ordinary literal. 381 """ 382 def resolve_api_name(n, rawtext, text, lineno, inliner, 383 options={}, content=[]): 384 if docutils is None: 385 raise AssertionError('requires docutils') 386 387 # node in monotype font 388 text = utils.unescape(text) 389 node = nodes.literal(rawtext, text, **options) 390 391 # Get the resolver from the register and create an url from it. 392 try: 393 url = api_register[name].get_url(text) 394 except IndexError, exc: 395 msg = inliner.reporter.warning(str(exc), line=lineno) 396 if problematic: 397 prb = inliner.problematic(rawtext, text, msg) 398 return [prb], [msg] 399 else: 400 return [node], [] 401 402 if url is not None: 403 node = nodes.reference(rawtext, '', node, refuri=url, **options) 404 return [node], []
    405 406 roles.register_local_role(name, resolve_api_name) 407 408 409 #{ Command line parsing 410 # -------------------- 411 412
    413 -def split_name(value):
    414 """ 415 Split an option in form ``NAME:VALUE`` and check if ``NAME`` exists. 416 """ 417 parts = value.split(':', 1) 418 if len(parts) != 2: 419 raise OptionValueError( 420 "option value must be specified as NAME:VALUE; got '%s' instead" 421 % value) 422 423 name, val = parts 424 425 if name not in api_register: 426 raise OptionValueError( 427 "the name '%s' has not been registered; use --external-api" 428 % name) 429 430 return (name, val)
    431 432
    433 -class ApiLinkReader(Reader):
    434 """ 435 A Docutils standalone reader allowing external documentation links. 436 437 The reader configure the url resolvers at the time `read()` is invoked the 438 first time. 439 """ 440 #: The option parser configuration. 441 settings_spec = ( 442 'API Linking Options', 443 None, 444 (( 445 'Define a new API document. A new interpreted text role NAME will be ' 446 'added.', 447 ['--external-api'], 448 {'metavar': 'NAME', 'action': 'append'} 449 ), ( 450 'Use records in FILENAME to resolve objects in the API named NAME.', 451 ['--external-api-file'], 452 {'metavar': 'NAME:FILENAME', 'action': 'append'} 453 ), ( 454 'Use STRING as prefix for the URL generated from the API NAME.', 455 ['--external-api-root'], 456 {'metavar': 'NAME:STRING', 'action': 'append'} 457 ),)) + Reader.settings_spec 458
    459 - def __init__(self, *args, **kwargs):
    460 if docutils is None: 461 raise AssertionError('requires docutils') 462 Reader.__init__(self, *args, **kwargs)
    463
    464 - def read(self, source, parser, settings):
    465 self.read_configuration(settings, problematic=True) 466 return Reader.read(self, source, parser, settings)
    467
    468 - def read_configuration(self, settings, problematic=True):
    469 """ 470 Read the configuration for the configured URL resolver. 471 472 Register a new role for each configured API. 473 474 :Parameters: 475 `settings` 476 the settings structure containing the options to read. 477 `problematic` : `bool` 478 if True, the registered role will create problematic nodes in 479 case of failed references. If False, a warning will be raised 480 anyway, but the output will appear as an ordinary literal. 481 """ 482 # Read config only once 483 if hasattr(self, '_conf'): 484 return 485 ApiLinkReader._conf = True 486 487 try: 488 if settings.external_api is not None: 489 for name in settings.external_api: 490 register_api(name) 491 create_api_role(name, problematic=problematic) 492 493 if settings.external_api_file is not None: 494 for name, file in map(split_name, settings.external_api_file): 495 set_api_file(name, file) 496 497 if settings.external_api_root is not None: 498 for name, root in map(split_name, settings.external_api_root): 499 set_api_root(name, root) 500 501 except OptionValueError, exc: 502 print >>sys.stderr, "%s: %s" % (exc.__class__.__name__, exc) 503 sys.exit(2)
    504 505 read_configuration = classmethod(read_configuration)
    506

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.javadoc-pysrc.html0000644000175000017500000022577310750103050023735 0ustar pronovicpronovic epydoc.markup.javadoc
    Package epydoc :: Package markup :: Module javadoc
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.markup.javadoc

      1  # 
      2  # javadoc.py: javadoc docstring parsing 
      3  # Edward Loper 
      4  # 
      5  # Created [07/03/03 12:37 PM] 
      6  # $Id: javadoc.py 1574 2007-03-07 02:55:14Z dvarrazzo $ 
      7  # 
      8   
      9  """ 
     10  Epydoc parser for U{Javadoc<http://java.sun.com/j2se/javadoc/>} 
     11  docstrings.  Javadoc is an HTML-based markup language that was 
     12  developed for documenting Java APIs with inline comments.  It consists 
     13  of raw HTML, augmented by Javadoc tags.  There are two types of 
     14  Javadoc tag: 
     15   
     16    - X{Javadoc block tags} correspond to Epydoc fields.  They are 
     17      marked by starting a line with a string of the form \"C{@M{tag} 
     18      [M{arg}]}\", where C{M{tag}} indicates the type of block, and 
     19      C{M{arg}} is an optional argument.  (For fields that take 
     20      arguments, Javadoc assumes that the single word immediately 
     21      following the tag is an argument; multi-word arguments cannot be 
     22      used with javadoc.)   
     23     
     24    - X{inline Javadoc tags} are used for inline markup.  In particular, 
     25      epydoc uses them for crossreference links between documentation. 
     26      Inline tags may appear anywhere in the text, and have the form 
     27      \"C{{@M{tag} M{[args...]}}}\", where C{M{tag}} indicates the 
     28      type of inline markup, and C{M{args}} are optional arguments. 
     29   
     30  Epydoc supports all Javadoc tags, I{except}: 
     31    - C{{@docRoot}}, which gives the (relative) URL of the generated 
     32      documentation's root. 
     33    - C{{@inheritDoc}}, which copies the documentation of the nearest 
     34      overridden object.  This can be used to combine the documentation 
     35      of the overridden object with the documentation of the 
     36      overridding object. 
     37    - C{@serial}, C{@serialField}, and C{@serialData} which describe the 
     38      serialization (pickling) of an object. 
     39    - C{{@value}}, which copies the value of a constant. 
     40   
     41  @warning: Epydoc only supports HTML output for Javadoc docstrings. 
     42  """ 
     43  __docformat__ = 'epytext en' 
     44   
     45  # Imports 
     46  import re 
     47  from xml.dom.minidom import * 
     48  from epydoc.markup import * 
     49   
    
    50 -def parse_docstring(docstring, errors, **options):
    51 """ 52 Parse the given docstring, which is formatted using Javadoc; and 53 return a C{ParsedDocstring} representation of its contents. 54 @param docstring: The docstring to parse 55 @type docstring: C{string} 56 @param errors: A list where any errors generated during parsing 57 will be stored. 58 @type errors: C{list} of L{ParseError} 59 @param options: Extra options. Unknown options are ignored. 60 Currently, no extra options are defined. 61 @rtype: L{ParsedDocstring} 62 """ 63 return ParsedJavadocDocstring(docstring, errors)
    64
    65 -class ParsedJavadocDocstring(ParsedDocstring):
    66 """ 67 An encoded version of a Javadoc docstring. Since Javadoc is a 68 fairly simple markup language, we don't do any processing in 69 advance; instead, we wait to split fields or resolve 70 crossreference links until we need to. 71 72 @group Field Splitting: split_fields, _ARG_FIELDS, _FIELD_RE 73 @cvar _ARG_FIELDS: A list of the fields that take arguments. 74 Since Javadoc doesn't mark arguments in any special way, we 75 must consult this list to decide whether the first word of a 76 field is an argument or not. 77 @cvar _FIELD_RE: A regular expression used to search for Javadoc 78 block tags. 79 80 @group HTML Output: to_html, _LINK_SPLIT_RE, _LINK_RE 81 @cvar _LINK_SPLIT_RE: A regular expression used to search for 82 Javadoc inline tags. 83 @cvar _LINK_RE: A regular expression used to process Javadoc 84 inline tags. 85 """
    86 - def __init__(self, docstring, errors=None):
    87 """ 88 Create a new C{ParsedJavadocDocstring}. 89 90 @param docstring: The docstring that should be used to 91 construct this C{ParsedJavadocDocstring}. 92 @type docstring: C{string} 93 @param errors: A list where any errors generated during 94 parsing will be stored. If no list is given, then 95 all errors are ignored. 96 @type errors: C{list} of L{ParseError} 97 """ 98 self._docstring = docstring 99 if errors is None: errors = [] 100 self._check_links(errors)
    101 102 #//////////////////////////////////////////////////////////// 103 # Field Splitting 104 #//////////////////////////////////////////////////////////// 105 106 _ARG_FIELDS = ('group variable var type cvariable cvar ivariable '+ 107 'ivar param '+ 108 'parameter arg argument raise raises exception '+ 109 'except deffield newfield keyword kwarg kwparam').split() 110 _FIELD_RE = re.compile(r'(^\s*\@\w+[\s$])', re.MULTILINE) 111 112 # Inherit docs from ParsedDocstring.
    113 - def split_fields(self, errors=None):
    114 115 # Split the docstring into an alternating list of field tags 116 # and text (odd pieces are field tags). 117 pieces = self._FIELD_RE.split(self._docstring) 118 119 # The first piece is the description. 120 descr = ParsedJavadocDocstring(pieces[0]) 121 122 # The remaining pieces are the block fields (alternating tags 123 # and bodies; odd pieces are tags). 124 fields = [] 125 for i in range(1, len(pieces)): 126 if i%2 == 1: 127 # Get the field tag. 128 tag = pieces[i].strip()[1:] 129 else: 130 # Get the field argument (if appropriate). 131 if tag in self._ARG_FIELDS: 132 subpieces = pieces[i].strip().split(None, 1)+['',''] 133 (arg, body) = subpieces[:2] 134 else: 135 (arg, body) = (None, pieces[i]) 136 137 # Special processing for @see fields, since Epydoc 138 # allows unrestricted text in them, but Javadoc just 139 # uses them for xref links: 140 if tag == 'see' and body: 141 if body[0] in '"\'': 142 if body[-1] == body[0]: body = body[1:-1] 143 elif body[0] == '<': pass 144 else: body = '{@link %s}' % body 145 146 # Construct the field. 147 parsed_body = ParsedJavadocDocstring(body) 148 fields.append(Field(tag, arg, parsed_body)) 149 150 if pieces[0].strip(): 151 return (descr, fields) 152 else: 153 return (None, fields)
    154 155 #//////////////////////////////////////////////////////////// 156 # HTML Output. 157 #//////////////////////////////////////////////////////////// 158 159 _LINK_SPLIT_RE = re.compile(r'({@link(?:plain)?\s[^}]+})') 160 _LINK_RE = re.compile(r'{@link(?:plain)?\s+' + r'([\w#.]+)' + 161 r'(?:\([^\)]*\))?' + r'(\s+.*)?' + r'}') 162 163 # Inherit docs from ParsedDocstring.
    164 - def to_html(self, docstring_linker, **options):
    165 # Split the docstring into an alternating list of HTML and 166 # links (odd pieces are links). 167 pieces = self._LINK_SPLIT_RE.split(self._docstring) 168 169 # This function is used to translate {@link ...}s to HTML. 170 translate_xref = docstring_linker.translate_identifier_xref 171 172 # Build up the HTML string from the pieces. For HTML pieces 173 # (even), just add it to html. For link pieces (odd), use 174 # docstring_linker to translate the crossreference link to 175 # HTML for us. 176 html = '' 177 for i in range(len(pieces)): 178 if i%2 == 0: 179 html += pieces[i] 180 else: 181 # Decompose the link into pieces. 182 m = self._LINK_RE.match(pieces[i]) 183 if m is None: continue # Error flagged by _check_links 184 (target, name) = m.groups() 185 186 # Normalize the target name. 187 if target[0] == '#': target = target[1:] 188 target = target.replace('#', '.') 189 target = re.sub(r'\(.*\)', '', target) 190 191 # Provide a name, if it wasn't specified. 192 if name is None: name = target 193 else: name = name.strip() 194 195 # Use docstring_linker to convert the name to html. 196 html += translate_xref(target, name) 197 return html
    198 212 213 #//////////////////////////////////////////////////////////// 214 # Plaintext Output. 215 #//////////////////////////////////////////////////////////// 216 217 # Inherit docs from ParsedDocstring. Since we don't define 218 # to_latex, this is used when generating latex output.
    219 - def to_plaintext(self, docstring_linker, **options):
    220 return self._docstring
    221 222 _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)') 223 224 # Jeff's hack to get summary working
    225 - def summary(self):
    226 # Drop tags 227 doc = "\n".join([ row for row in self._docstring.split('\n') 228 if not row.lstrip().startswith('@') ]) 229 230 m = self._SUMMARY_RE.match(doc) 231 if m: 232 other = doc[m.end():] 233 return (ParsedJavadocDocstring(m.group(1)), 234 other != '' and not other.isspace()) 235 236 else: 237 parts = doc.strip('\n').split('\n', 1) 238 if len(parts) == 1: 239 summary = parts[0] 240 other = False 241 else: 242 summary = parts[0] + '...' 243 other = True 244 245 return ParsedJavadocDocstring(summary), other
    246 247 # def concatenate(self, other): 248 # if not isinstance(other, ParsedJavadocDocstring): 249 # raise ValueError, 'Could not concatenate docstrings' 250 # return ParsedJavadocDocstring(self._docstring+other._docstring) 251

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._SplitFieldsTranslator-class.html0000644000175000017500000011126410750103050032352 0ustar pronovicpronovic epydoc.markup.restructuredtext._SplitFieldsTranslator
    Package epydoc :: Package markup :: Module restructuredtext :: Class _SplitFieldsTranslator
    [hide private]
    [frames] | no frames]

    Class _SplitFieldsTranslator

    source code


    A docutils translator that removes all fields from a document, and collects them into the instance variable fields

    Instance Methods [hide private]
     
    __init__(self, document, errors) source code
    call graph 
     
    visit_document(self, node) source code
    call graph 
     
    visit_field(self, node) source code
    call graph 
     
    _add_field(self, tagname, arg, fbody) source code
    call graph 
     
    visit_field_list(self, node) source code
    call graph 
     
    handle_consolidated_field(self, body, tagname)
    Attempt to handle a consolidated section.
    source code
    call graph 
     
    handle_consolidated_bullet_list(self, items, tagname) source code
    call graph 
     
    handle_consolidated_definition_list(self, items, tagname) source code
    call graph 
     
    unknown_visit(self, node)
    Ignore all unknown nodes
    source code
    call graph 

    Inherited from docutils.nodes.NodeVisitor: dispatch_departure, dispatch_visit, unknown_departure

    Class Variables [hide private]
      ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD = True
    If true, then consolidated fields are not required to mark arguments with `backticks`.

    Inherited from docutils.nodes.NodeVisitor: optional

    Instance Variables [hide private]
    list of Field fields
    The fields of the most recently walked document.
    Method Details [hide private]

    __init__(self, document, errors)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.nodes.NodeVisitor.__init__

    unknown_visit(self, node)

    source code 
    call graph 

    Ignore all unknown nodes

    Overrides: docutils.nodes.NodeVisitor.unknown_visit

    Class Variable Details [hide private]

    ALLOW_UNMARKED_ARG_IN_CONSOLIDATED_FIELD

    If true, then consolidated fields are not required to mark arguments with `backticks`. (This is currently only implemented for consolidated fields expressed as definition lists; consolidated fields expressed as unordered lists still require backticks for now.

    Value:
    True
    

    epydoc-3.0.1+dfsg/doc/api/toc-epydoc.docwriter.dotgraph-module.html0000644000175000017500000001022310750103050025527 0ustar pronovicpronovic dotgraph

    Module dotgraph


    Classes

    DotGraph
    DotGraphEdge
    DotGraphNode
    DotGraphUmlClassNode
    DotGraphUmlModuleNode

    Functions

    add_valdoc_nodes
    call_graph
    class_tree_graph
    get_dot_version
    import_graph
    name_list
    package_tree_graph
    specialize_valdoc_node
    uml_class_tree_graph
    uml_package_tree_graph

    Variables

    BASECLASS_BG
    CLASS_BG
    DOT_COMMAND
    INH_LINK_COLOR
    MODULE_BG
    MODULE_NODE_HTML
    NOOP_URL
    ROUTINE_BG
    SELECTED_BG
    SUBCLASS_BG

    [hide private] epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_css-pysrc.html0000644000175000017500000032377310750103050024644 0ustar pronovicpronovic epydoc.docwriter.html_css
    Package epydoc :: Package docwriter :: Module html_css
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.html_css

      1  # 
      2  # epydoc.css: default epydoc CSS stylesheets 
      3  # Edward Loper 
      4  # 
      5  # Created [01/30/01 05:18 PM] 
      6  # $Id: html_css.py 1634 2007-09-24 15:58:38Z dvarrazzo $ 
      7  # 
      8   
      9  """ 
     10  Predefined CSS stylesheets for the HTML outputter (L{epydoc.docwriter.html}). 
     11   
     12  @type STYLESHEETS: C{dictionary} from C{string} to C{(string, string)} 
     13  @var STYLESHEETS: A dictionary mapping from stylesheet names to CSS 
     14      stylesheets and descriptions.  A single stylesheet may have 
     15      multiple names.  Currently, the following stylesheets are defined: 
     16        - C{default}: The default stylesheet (synonym for C{white}). 
     17        - C{white}: Black on white, with blue highlights (similar to 
     18          javadoc). 
     19        - C{blue}: Black on steel blue. 
     20        - C{green}: Black on green. 
     21        - C{black}: White on black, with blue highlights 
     22        - C{grayscale}: Grayscale black on white. 
     23        - C{none}: An empty stylesheet. 
     24  """ 
     25  __docformat__ = 'epytext en' 
     26   
     27  import re 
     28   
     29  ############################################################ 
     30  ## Basic stylesheets 
     31  ############################################################ 
     32   
     33  # [xx] Should I do something like: 
     34  # 
     35  #    @import url(html4css1.css); 
     36  # 
     37  # But then where do I get that css file from?  Hm. 
     38  # Also, in principle I'm mangling classes, but it looks like I'm 
     39  # failing. 
     40  # 
     41   
     42  # Black on white, with blue highlights.  This is similar to how 
     43  # javadoc looks. 
     44  TEMPLATE = """ 
     45   
     46  /* Epydoc CSS Stylesheet 
     47   * 
     48   * This stylesheet can be used to customize the appearance of epydoc's 
     49   * HTML output. 
     50   * 
     51   */ 
     52   
     53  /* Default Colors & Styles 
     54   *   - Set the default foreground & background color with 'body'; and  
     55   *     link colors with 'a:link' and 'a:visited'. 
     56   *   - Use bold for decision list terms. 
     57   *   - The heading styles defined here are used for headings *within* 
     58   *     docstring descriptions.  All headings used by epydoc itself use 
     59   *     either class='epydoc' or class='toc' (CSS styles for both 
     60   *     defined below). 
     61   */ 
     62  body                        { background: $body_bg; color: $body_fg; } 
     63  p                           { margin-top: 0.5em; margin-bottom: 0.5em; } 
     64  a:link                      { color: $body_link; } 
     65  a:visited                   { color: $body_visited_link; } 
     66  dt                          { font-weight: bold; } 
     67  h1                          { font-size: +140%; font-style: italic; 
     68                                font-weight: bold; } 
     69  h2                          { font-size: +125%; font-style: italic; 
     70                                font-weight: bold; } 
     71  h3                          { font-size: +110%; font-style: italic; 
     72                                font-weight: normal; } 
     73  code                        { font-size: 100%; } 
     74  /* N.B.: class, not pseudoclass */ 
     75  a.link                      { font-family: monospace; } 
     76    
     77  /* Page Header & Footer 
     78   *   - The standard page header consists of a navigation bar (with 
     79   *     pointers to standard pages such as 'home' and 'trees'); a 
     80   *     breadcrumbs list, which can be used to navigate to containing 
     81   *     classes or modules; options links, to show/hide private 
     82   *     variables and to show/hide frames; and a page title (using 
     83   *     <h1>).  The page title may be followed by a link to the 
     84   *     corresponding source code (using 'span.codelink'). 
     85   *   - The footer consists of a navigation bar, a timestamp, and a 
     86   *     pointer to epydoc's homepage. 
     87   */  
     88  h1.epydoc                   { margin: 0; font-size: +140%; font-weight: bold; } 
     89  h2.epydoc                   { font-size: +130%; font-weight: bold; } 
     90  h3.epydoc                   { font-size: +115%; font-weight: bold; 
     91                                margin-top: 0.2em; } 
     92  td h3.epydoc                { font-size: +115%; font-weight: bold; 
     93                                margin-bottom: 0; } 
     94  table.navbar                { background: $navbar_bg; color: $navbar_fg; 
     95                                border: $navbar_border; } 
     96  table.navbar table          { color: $navbar_fg; } 
     97  th.navbar-select            { background: $navbar_select_bg; 
     98                                color: $navbar_select_fg; }  
     99  table.navbar a              { text-decoration: none; }   
    100  table.navbar a:link         { color: $navbar_link; } 
    101  table.navbar a:visited      { color: $navbar_visited_link; } 
    102  span.breadcrumbs            { font-size: 85%; font-weight: bold; } 
    103  span.options                { font-size: 70%; } 
    104  span.codelink               { font-size: 85%; } 
    105  td.footer                   { font-size: 85%; } 
    106   
    107  /* Table Headers 
    108   *   - Each summary table and details section begins with a 'header' 
    109   *     row.  This row contains a section title (marked by 
    110   *     'span.table-header') as well as a show/hide private link 
    111   *     (marked by 'span.options', defined above). 
    112   *   - Summary tables that contain user-defined groups mark those 
    113   *     groups using 'group header' rows. 
    114   */ 
    115  td.table-header             { background: $table_hdr_bg; color: $table_hdr_fg; 
    116                                border: $table_border; } 
    117  td.table-header table       { color: $table_hdr_fg; } 
    118  td.table-header table a:link      { color: $table_hdr_link; } 
    119  td.table-header table a:visited   { color: $table_hdr_visited_link; } 
    120  span.table-header           { font-size: 120%; font-weight: bold; } 
    121  th.group-header             { background: $group_hdr_bg; color: $group_hdr_fg; 
    122                                text-align: left; font-style: italic;  
    123                                font-size: 115%;  
    124                                border: $table_border; } 
    125   
    126  /* Summary Tables (functions, variables, etc) 
    127   *   - Each object is described by a single row of the table with 
    128   *     two cells.  The left cell gives the object's type, and is 
    129   *     marked with 'code.summary-type'.  The right cell gives the 
    130   *     object's name and a summary description. 
    131   *   - CSS styles for the table's header and group headers are 
    132   *     defined above, under 'Table Headers' 
    133   */ 
    134  table.summary               { border-collapse: collapse; 
    135                                background: $table_bg; color: $table_fg; 
    136                                border: $table_border; 
    137                                margin-bottom: 0.5em; } 
    138  td.summary                  { border: $table_border; } 
    139  code.summary-type           { font-size: 85%; } 
    140  table.summary a:link        { color: $table_link; } 
    141  table.summary a:visited     { color: $table_visited_link; } 
    142   
    143   
    144  /* Details Tables (functions, variables, etc) 
    145   *   - Each object is described in its own div. 
    146   *   - A single-row summary table w/ table-header is used as 
    147   *     a header for each details section (CSS style for table-header 
    148   *     is defined above, under 'Table Headers'). 
    149   */ 
    150  table.details               { border-collapse: collapse; 
    151                                background: $table_bg; color: $table_fg; 
    152                                border: $table_border; 
    153                                margin: .2em 0 0 0; } 
    154  table.details table         { color: $table_fg; } 
    155  table.details a:link        { color: $table_link; } 
    156  table.details a:visited     { color: $table_visited_link; } 
    157   
    158  /* Fields */ 
    159  dl.fields                   { margin-left: 2em; margin-top: 1em; 
    160                                margin-bottom: 1em; } 
    161  dl.fields dd ul             { margin-left: 0em; padding-left: 0em; } 
    162  dl.fields dd ul li ul       { margin-left: 2em; padding-left: 0em; } 
    163  div.fields                  { margin-left: 2em; } 
    164  div.fields p                { margin-bottom: 0.5em; } 
    165   
    166  /* Index tables (identifier index, term index, etc) 
    167   *   - link-index is used for indices containing lists of links 
    168   *     (namely, the identifier index & term index). 
    169   *   - index-where is used in link indices for the text indicating 
    170   *     the container/source for each link. 
    171   *   - metadata-index is used for indices containing metadata 
    172   *     extracted from fields (namely, the bug index & todo index). 
    173   */ 
    174  table.link-index            { border-collapse: collapse; 
    175                                background: $table_bg; color: $table_fg; 
    176                                border: $table_border; } 
    177  td.link-index               { border-width: 0px; } 
    178  table.link-index a:link     { color: $table_link; } 
    179  table.link-index a:visited  { color: $table_visited_link; } 
    180  span.index-where            { font-size: 70%; } 
    181  table.metadata-index        { border-collapse: collapse; 
    182                                background: $table_bg; color: $table_fg; 
    183                                border: $table_border;  
    184                                margin: .2em 0 0 0; } 
    185  td.metadata-index           { border-width: 1px; border-style: solid; } 
    186  table.metadata-index a:link { color: $table_link; } 
    187  table.metadata-index a:visited  { color: $table_visited_link; } 
    188   
    189  /* Function signatures 
    190   *   - sig* is used for the signature in the details section. 
    191   *   - .summary-sig* is used for the signature in the summary  
    192   *     table, and when listing property accessor functions. 
    193   * */ 
    194  .sig-name                   { color: $sig_name; } 
    195  .sig-arg                    { color: $sig_arg; } 
    196  .sig-default                { color: $sig_default; } 
    197  .summary-sig                { font-family: monospace; } 
    198  .summary-sig-name           { color: $summary_sig_name; font-weight: bold; } 
    199  table.summary a.summary-sig-name:link 
    200                              { color: $summary_sig_name; font-weight: bold; } 
    201  table.summary a.summary-sig-name:visited 
    202                              { color: $summary_sig_name; font-weight: bold; } 
    203  .summary-sig-arg            { color: $summary_sig_arg; } 
    204  .summary-sig-default        { color: $summary_sig_default; } 
    205   
    206  /* Subclass list 
    207   */ 
    208  ul.subclass-list { display: inline; } 
    209  ul.subclass-list li { display: inline; } 
    210   
    211  /* To render variables, classes etc. like functions */ 
    212  table.summary .summary-name { color: $summary_sig_name; font-weight: bold; 
    213                                font-family: monospace; } 
    214  table.summary 
    215       a.summary-name:link    { color: $summary_sig_name; font-weight: bold; 
    216                                font-family: monospace; } 
    217  table.summary 
    218      a.summary-name:visited  { color: $summary_sig_name; font-weight: bold; 
    219                                font-family: monospace; } 
    220   
    221  /* Variable values 
    222   *   - In the 'variable details' sections, each varaible's value is 
    223   *     listed in a 'pre.variable' box.  The width of this box is 
    224   *     restricted to 80 chars; if the value's repr is longer than 
    225   *     this it will be wrapped, using a backslash marked with 
    226   *     class 'variable-linewrap'.  If the value's repr is longer 
    227   *     than 3 lines, the rest will be ellided; and an ellipsis 
    228   *     marker ('...' marked with 'variable-ellipsis') will be used. 
    229   *   - If the value is a string, its quote marks will be marked 
    230   *     with 'variable-quote'. 
    231   *   - If the variable is a regexp, it is syntax-highlighted using 
    232   *     the re* CSS classes. 
    233   */ 
    234  pre.variable                { padding: .5em; margin: 0; 
    235                                background: $variable_bg; color: $variable_fg; 
    236                                border: $variable_border; } 
    237  .variable-linewrap          { color: $variable_linewrap; font-weight: bold; } 
    238  .variable-ellipsis          { color: $variable_ellipsis; font-weight: bold; } 
    239  .variable-quote             { color: $variable_quote; font-weight: bold; } 
    240  .variable-group             { color: $variable_group; font-weight: bold; } 
    241  .variable-op                { color: $variable_op; font-weight: bold; } 
    242  .variable-string            { color: $variable_string; } 
    243  .variable-unknown           { color: $variable_unknown; font-weight: bold; } 
    244  .re                         { color: $re; } 
    245  .re-char                    { color: $re_char; } 
    246  .re-op                      { color: $re_op; } 
    247  .re-group                   { color: $re_group; } 
    248  .re-ref                     { color: $re_ref; } 
    249   
    250  /* Base tree 
    251   *   - Used by class pages to display the base class hierarchy. 
    252   */ 
    253  pre.base-tree               { font-size: 80%; margin: 0; } 
    254   
    255  /* Frames-based table of contents headers 
    256   *   - Consists of two frames: one for selecting modules; and 
    257   *     the other listing the contents of the selected module. 
    258   *   - h1.toc is used for each frame's heading 
    259   *   - h2.toc is used for subheadings within each frame. 
    260   */ 
    261  h1.toc                      { text-align: center; font-size: 105%; 
    262                                margin: 0; font-weight: bold; 
    263                                padding: 0; } 
    264  h2.toc                      { font-size: 100%; font-weight: bold;  
    265                                margin: 0.5em 0 0 -0.3em; } 
    266   
    267  /* Syntax Highlighting for Source Code 
    268   *   - doctest examples are displayed in a 'pre.py-doctest' block. 
    269   *     If the example is in a details table entry, then it will use 
    270   *     the colors specified by the 'table pre.py-doctest' line. 
    271   *   - Source code listings are displayed in a 'pre.py-src' block. 
    272   *     Each line is marked with 'span.py-line' (used to draw a line 
    273   *     down the left margin, separating the code from the line 
    274   *     numbers).  Line numbers are displayed with 'span.py-lineno'. 
    275   *     The expand/collapse block toggle button is displayed with 
    276   *     'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not 
    277   *     modify the font size of the text.) 
    278   *   - If a source code page is opened with an anchor, then the 
    279   *     corresponding code block will be highlighted.  The code 
    280   *     block's header is highlighted with 'py-highlight-hdr'; and 
    281   *     the code block's body is highlighted with 'py-highlight'. 
    282   *   - The remaining py-* classes are used to perform syntax 
    283   *     highlighting (py-string for string literals, py-name for names, 
    284   *     etc.) 
    285   */ 
    286  pre.py-doctest              { padding: .5em; margin: 1em; 
    287                                background: $doctest_bg; color: $doctest_fg; 
    288                                border: $doctest_border; } 
    289  table pre.py-doctest        { background: $doctest_in_table_bg; 
    290                                color: $doctest_in_table_fg; } 
    291  pre.py-src                  { border: $pysrc_border;  
    292                                background: $pysrc_bg; color: $pysrc_fg; } 
    293  .py-line                    { border-left: $pysrc_sep_border;  
    294                                margin-left: .2em; padding-left: .4em; } 
    295  .py-lineno                  { font-style: italic; font-size: 90%; 
    296                                padding-left: .5em; } 
    297  a.py-toggle                 { text-decoration: none; } 
    298  div.py-highlight-hdr        { border-top: $pysrc_border; 
    299                                border-bottom: $pysrc_border; 
    300                                background: $pysrc_highlight_hdr_bg; } 
    301  div.py-highlight            { border-bottom: $pysrc_border; 
    302                                background: $pysrc_highlight_bg; } 
    303  .py-prompt                  { color: $py_prompt; font-weight: bold;} 
    304  .py-more                    { color: $py_more; font-weight: bold;} 
    305  .py-string                  { color: $py_string; } 
    306  .py-comment                 { color: $py_comment; } 
    307  .py-keyword                 { color: $py_keyword; } 
    308  .py-output                  { color: $py_output; } 
    309  .py-name                    { color: $py_name; } 
    310  .py-name:link               { color: $py_name !important; } 
    311  .py-name:visited            { color: $py_name !important; } 
    312  .py-number                  { color: $py_number; } 
    313  .py-defname                 { color: $py_def_name; font-weight: bold; } 
    314  .py-def-name                { color: $py_def_name; font-weight: bold; } 
    315  .py-base-class              { color: $py_base_class; } 
    316  .py-param                   { color: $py_param; } 
    317  .py-docstring               { color: $py_docstring; } 
    318  .py-decorator               { color: $py_decorator; } 
    319  /* Use this if you don't want links to names underlined: */ 
    320  /*a.py-name                   { text-decoration: none; }*/ 
    321   
    322  /* Graphs & Diagrams 
    323   *   - These CSS styles are used for graphs & diagrams generated using 
    324   *     Graphviz dot.  'img.graph-without-title' is used for bare 
    325   *     diagrams (to remove the border created by making the image 
    326   *     clickable). 
    327   */ 
    328  img.graph-without-title     { border: none; } 
    329  img.graph-with-title        { border: $graph_border; } 
    330  span.graph-title            { font-weight: bold; } 
    331  span.graph-caption          { } 
    332   
    333  /* General-purpose classes 
    334   *   - 'p.indent-wrapped-lines' defines a paragraph whose first line 
    335   *     is not indented, but whose subsequent lines are. 
    336   *   - The 'nomargin-top' class is used to remove the top margin (e.g. 
    337   *     from lists).  The 'nomargin' class is used to remove both the 
    338   *     top and bottom margin (but not the left or right margin -- 
    339   *     for lists, that would cause the bullets to disappear.) 
    340   */ 
    341  p.indent-wrapped-lines      { padding: 0 0 0 7em; text-indent: -7em;  
    342                                margin: 0; } 
    343  .nomargin-top               { margin-top: 0; } 
    344  .nomargin                   { margin-top: 0; margin-bottom: 0; } 
    345   
    346  /* HTML Log */ 
    347  div.log-block               { padding: 0; margin: .5em 0 .5em 0; 
    348                                background: $log_bg; color: $log_fg; 
    349                                border: $log_border; } 
    350  div.log-error               { padding: .1em .3em .1em .3em; margin: 4px; 
    351                                background: $log_error_bg; color: $log_error_fg; 
    352                                border: $log_error_border; } 
    353  div.log-warning             { padding: .1em .3em .1em .3em; margin: 4px; 
    354                                background: $log_warn_bg; color: $log_warn_fg; 
    355                                border: $log_warn_border; } 
    356  div.log-info               { padding: .1em .3em .1em .3em; margin: 4px; 
    357                                background: $log_info_bg; color: $log_info_fg; 
    358                                border: $log_info_border; } 
    359  h2.log-hdr                  { background: $log_hdr_bg; color: $log_hdr_fg; 
    360                                margin: 0; padding: 0em 0.5em 0em 0.5em; 
    361                                border-bottom: $log_border; font-size: 110%; } 
    362  p.log                       { font-weight: bold; margin: .5em 0 .5em 0; } 
    363  tr.opt-changed              { color: $opt_changed_fg; font-weight: bold; } 
    364  tr.opt-default              { color: $opt_default_fg; } 
    365  pre.log                     { margin: 0; padding: 0; padding-left: 1em; } 
    366  """  
    367   
    368  ############################################################ 
    369  ## Derived stylesheets 
    370  ############################################################ 
    371  # Use some simple manipulations to produce a wide variety of color 
    372  # schemes.  In particular, use th _COLOR_RE regular expression to 
    373  # search for colors, and to transform them in various ways. 
    374   
    375  _COLOR_RE = re.compile(r'#(..)(..)(..)') 
    376   
    
    377 -def _set_colors(template, *dicts):
    378 colors = dicts[0].copy() 379 for d in dicts[1:]: colors.update(d) 380 return re.sub(r'\$(\w+)', lambda m:colors[m.group(1)], template)
    381
    382 -def _rv(match):
    383 """ 384 Given a regexp match for a color, return the reverse-video version 385 of that color. 386 387 @param match: A regular expression match. 388 @type match: C{Match} 389 @return: The reverse-video color. 390 @rtype: C{string} 391 """ 392 rgb = [int(grp, 16) for grp in match.groups()] 393 return '#' + ''.join(['%02x' % (255-c) for c in rgb])
    394
    395 -def _darken_darks(match):
    396 rgb = [int(grp, 16) for grp in match.groups()] 397 return '#' + ''.join(['%02x' % (((c/255.)**2) * 255) for c in rgb])
    398 399 _WHITE_COLORS = dict( 400 # Defaults: 401 body_bg = '#ffffff', 402 body_fg = '#000000', 403 body_link = '#0000ff', 404 body_visited_link = '#204080', 405 # Navigation bar: 406 navbar_bg = '#a0c0ff', 407 navbar_fg = '#000000', 408 navbar_border = '2px groove #c0d0d0', 409 navbar_select_bg = '#70b0ff', 410 navbar_select_fg = '#000000', 411 navbar_link = '#0000ff', 412 navbar_visited_link = '#204080', 413 # Tables (summary tables, details tables, indices): 414 table_bg = '#e8f0f8', 415 table_fg = '#000000', 416 table_link = '#0000ff', 417 table_visited_link = '#204080', 418 table_border = '1px solid #608090', 419 table_hdr_bg = '#70b0ff', 420 table_hdr_fg = '#000000', 421 table_hdr_link = '#0000ff', 422 table_hdr_visited_link = '#204080', 423 group_hdr_bg = '#c0e0f8', 424 group_hdr_fg = '#000000', 425 # Function signatures: 426 sig_name = '#006080', 427 sig_arg = '#008060', 428 sig_default = '#602000', 429 summary_sig_name = '#006080', 430 summary_sig_arg = '#006040', 431 summary_sig_default = '#501800', 432 # Variable values: 433 variable_bg = '#dce4ec', 434 variable_fg = '#000000', 435 variable_border = '1px solid #708890', 436 variable_linewrap = '#604000', 437 variable_ellipsis = '#604000', 438 variable_quote = '#604000', 439 variable_group = '#008000', 440 variable_string = '#006030', 441 variable_op = '#604000', 442 variable_unknown = '#a00000', 443 re = '#000000', 444 re_char = '#006030', 445 re_op = '#600000', 446 re_group = '#003060', 447 re_ref = '#404040', 448 # Python source code: 449 doctest_bg = '#e8f0f8', 450 doctest_fg = '#000000', 451 doctest_border = '1px solid #708890', 452 doctest_in_table_bg = '#dce4ec', 453 doctest_in_table_fg = '#000000', 454 pysrc_border = '2px solid #000000', 455 pysrc_sep_border = '2px solid #000000', 456 pysrc_bg = '#f0f0f0', 457 pysrc_fg = '#000000', 458 pysrc_highlight_hdr_bg = '#d8e8e8', 459 pysrc_highlight_bg = '#d0e0e0', 460 py_prompt = '#005050', 461 py_more = '#005050', 462 py_string = '#006030', 463 py_comment = '#003060', 464 py_keyword = '#600000', 465 py_output = '#404040', 466 py_name = '#000050', 467 py_number = '#005000', 468 py_def_name = '#000060', 469 py_base_class = '#000060', 470 py_param = '#000060', 471 py_docstring = '#006030', 472 py_decorator = '#804020', 473 # Graphs 474 graph_border = '1px solid #000000', 475 # Log block 476 log_bg = '#e8f0f8', 477 log_fg = '#000000', 478 log_border = '1px solid #000000', 479 log_hdr_bg = '#70b0ff', 480 log_hdr_fg = '#000000', 481 log_error_bg = '#ffb0b0', 482 log_error_fg = '#000000', 483 log_error_border = '1px solid #000000', 484 log_warn_bg = '#ffffb0', 485 log_warn_fg = '#000000', 486 log_warn_border = '1px solid #000000', 487 log_info_bg = '#b0ffb0', 488 log_info_fg = '#000000', 489 log_info_border = '1px solid #000000', 490 opt_changed_fg = '#000000', 491 opt_default_fg = '#606060', 492 ) 493 494 _BLUE_COLORS = _WHITE_COLORS.copy() 495 _BLUE_COLORS.update(dict( 496 # Body: white text on a dark blue background 497 body_bg = '#000070', 498 body_fg = '#ffffff', 499 body_link = '#ffffff', 500 body_visited_link = '#d0d0ff', 501 # Tables: cyan headers, black on white bodies 502 table_bg = '#ffffff', 503 table_fg = '#000000', 504 table_hdr_bg = '#70b0ff', 505 table_hdr_fg = '#000000', 506 table_hdr_link = '#000000', 507 table_hdr_visited_link = '#000000', 508 table_border = '1px solid #000000', 509 # Navigation bar: blue w/ cyan selection 510 navbar_bg = '#0000ff', 511 navbar_fg = '#ffffff', 512 navbar_link = '#ffffff', 513 navbar_visited_link = '#ffffff', 514 navbar_select_bg = '#70b0ff', 515 navbar_select_fg = '#000000', 516 navbar_border = '1px solid #70b0ff', 517 # Variable values & doctest blocks: cyan 518 variable_bg = '#c0e0f8', 519 variable_fg = '#000000', 520 doctest_bg = '#c0e0f8', 521 doctest_fg = '#000000', 522 doctest_in_table_bg = '#c0e0f8', 523 doctest_in_table_fg = '#000000', 524 )) 525 526 _WHITE = _set_colors(TEMPLATE, _WHITE_COLORS) 527 _BLUE = _set_colors(TEMPLATE, _BLUE_COLORS) 528 529 # Black-on-green 530 _GREEN = _COLOR_RE.sub(_darken_darks, _COLOR_RE.sub(r'#\1\3\2', _BLUE)) 531 532 # White-on-black, with blue highlights. 533 _BLACK = _COLOR_RE.sub(r'#\3\2\1', _COLOR_RE.sub(_rv, _WHITE)) 534 535 # Grayscale 536 _GRAYSCALE = _COLOR_RE.sub(r'#\2\2\2', _WHITE) 537 538 ############################################################ 539 ## Stylesheet table 540 ############################################################ 541 542 STYLESHEETS = { 543 'white': (_WHITE, "Black on white, with blue highlights"), 544 'blue': (_BLUE, "Black on steel blue"), 545 'green': (_GREEN, "Black on green"), 546 'black': (_BLACK, "White on black, with blue highlights"), 547 'grayscale': (_GRAYSCALE, "Grayscale black on white"), 548 'default': (_WHITE, "Default stylesheet (=white)"), 549 # 'none': (_LAYOUT, "A base stylesheet (no color modifications)"), 550 } 551

    epydoc-3.0.1+dfsg/doc/api/epydoc.log-pysrc.html0000644000175000017500000020500010750103050021566 0ustar pronovicpronovic epydoc.log
    Package epydoc :: Module log
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.log

      1  # epydoc -- Logging 
      2  # 
      3  # Copyright (C) 2005 Edward Loper 
      4  # Author: Edward Loper <edloper@loper.org> 
      5  # URL: <http://epydoc.sf.net> 
      6  # 
      7  # $Id: log.py 1488 2007-02-14 00:34:27Z edloper $ 
      8   
      9  """ 
     10  Functions used to report messages and progress updates to the user. 
     11  These functions are delegated to zero or more registered L{Logger} 
     12  objects, which are responsible for actually presenting the information 
     13  to the user.  Different interfaces are free to create and register 
     14  their own C{Logger}s, allowing them to present this information in the 
     15  manner that is best suited to each interface. 
     16   
     17  @note: I considered using the standard C{logging} package to provide 
     18  this functionality.  However, I found that it would be too difficult 
     19  to get that package to provide the behavior I want (esp. with respect 
     20  to progress displays; but also with respect to message blocks). 
     21   
     22  @group Message Severity Levels: DEBUG, INFO, WARNING, ERROR, FATAL 
     23  """ 
     24  __docformat__ = 'epytext en' 
     25   
     26  import sys, os 
     27   
     28  DEBUG = 10 
     29  INFO = 20 
     30  DOCSTRING_WARNING = 25 
     31  WARNING = 30 
     32  ERROR = 40 
     33  FATAL = 40 
     34   
     35  ###################################################################### 
     36  # Logger Base Class 
     37  ###################################################################### 
    
    38 -class Logger:
    39 """ 40 An abstract base class that defines the interface for X{loggers}, 41 which are used by epydoc to report information back to the user. 42 Loggers are responsible for tracking two types of information: 43 44 - Messages, such as warnings and errors. 45 - Progress on the current task. 46 47 This abstract class allows the command-line interface and the 48 graphical interface to each present this information to the user 49 in the way that's most natural for each interface. To set up a 50 logger, create a subclass of C{Logger} that overrides all methods, 51 and register it using L{register_logger}. 52 """ 53 #//////////////////////////////////////////////////////////// 54 # Messages 55 #//////////////////////////////////////////////////////////// 56
    57 - def log(self, level, message):
    58 """ 59 Display a message. 60 61 @param message: The message string to display. C{message} may 62 contain newlines, but does not need to end in a newline. 63 @param level: An integer value indicating the severity of the 64 message. 65 """
    66
    67 - def close(self):
    68 """ 69 Perform any tasks needed to close this logger. 70 """
    71 72 #//////////////////////////////////////////////////////////// 73 # Message blocks 74 #//////////////////////////////////////////////////////////// 75
    76 - def start_block(self, header):
    77 """ 78 Start a new message block. Any calls to L{info()}, 79 L{warning()}, or L{error()} that occur between a call to 80 C{start_block} and a corresponding call to C{end_block} will 81 be grouped together, and displayed with a common header. 82 C{start_block} can be called multiple times (to form nested 83 blocks), but every call to C{start_block} I{must} be balanced 84 by a call to C{end_block}. 85 """
    86
    87 - def end_block(self):
    88 """ 89 End a warning block. See L{start_block} for details. 90 """
    91 92 #//////////////////////////////////////////////////////////// 93 # Progress bar 94 #//////////////////////////////////////////////////////////// 95
    96 - def start_progress(self, header=None):
    97 """ 98 Begin displaying progress for a new task. C{header} is a 99 description of the task for which progress is being reported. 100 Each call to C{start_progress} must be followed by a call to 101 C{end_progress} (with no intervening calls to 102 C{start_progress}). 103 """
    104
    105 - def end_progress(self):
    106 """ 107 Finish off the display of progress for the current task. See 108 L{start_progress} for more information. 109 """
    110
    111 - def progress(self, percent, message=''):
    112 """ 113 Update the progress display. 114 115 @param percent: A float from 0.0 to 1.0, indicating how much 116 progress has been made. 117 @param message: A message indicating the most recent action 118 that contributed towards that progress. 119 """
    120
    121 -class SimpleLogger(Logger):
    122 - def __init__(self, threshold=WARNING):
    123 self.threshold = threshold
    124 - def log(self, level, message):
    125 if level >= self.threshold: print message
    126 127 ###################################################################### 128 # Logger Registry 129 ###################################################################### 130 131 _loggers = [] 132 """ 133 The list of registered logging functions. 134 """ 135
    136 -def register_logger(logger):
    137 """ 138 Register a logger. Each call to one of the logging functions 139 defined by this module will be delegated to each registered 140 logger. 141 """ 142 _loggers.append(logger)
    143
    144 -def remove_logger(logger):
    145 _loggers.remove(logger)
    146 147 ###################################################################### 148 # Logging Functions 149 ###################################################################### 150 # The following methods all just delegate to the corresponding 151 # methods in the Logger class (above) for each registered logger. 152
    153 -def fatal(*messages):
    154 """Display the given fatal message.""" 155 message = ' '.join(['%s' % (m,) for m in messages]) 156 for logger in _loggers: logger.log(FATAL, message)
    157
    158 -def error(*messages):
    159 """Display the given error message.""" 160 message = ' '.join(['%s' % (m,) for m in messages]) 161 for logger in _loggers: logger.log(ERROR, message)
    162
    163 -def warning(*messages):
    164 """Display the given warning message.""" 165 message = ' '.join(['%s' % (m,) for m in messages]) 166 for logger in _loggers: logger.log(WARNING, message)
    167
    168 -def docstring_warning(*messages):
    169 """Display the given docstring warning message.""" 170 message = ' '.join(['%s' % (m,) for m in messages]) 171 for logger in _loggers: logger.log(DOCSTRING_WARNING, message)
    172
    173 -def info(*messages):
    174 """Display the given informational message.""" 175 message = ' '.join(['%s' % (m,) for m in messages]) 176 for logger in _loggers: logger.log(INFO, message)
    177
    178 -def debug(*messages):
    179 """Display the given debugging message.""" 180 message = ' '.join(['%s' % (m,) for m in messages]) 181 for logger in _loggers: logger.log(DEBUG, message)
    182
    183 -def start_block(header):
    184 for logger in _loggers: logger.start_block(header)
    185 start_block.__doc__ = Logger.start_block.__doc__ 186
    187 -def end_block():
    188 for logger in _loggers: logger.end_block()
    189 end_block.__doc__ = Logger.end_block.__doc__ 190
    191 -def start_progress(header=None):
    192 for logger in _loggers: logger.start_progress(header)
    193 start_progress.__doc__ = Logger.start_progress.__doc__ 194
    195 -def end_progress():
    196 for logger in _loggers: logger.end_progress()
    197 end_progress.__doc__ = Logger.end_progress.__doc__ 198
    199 -def progress(percent, message=''):
    200 for logger in _loggers: logger.progress(percent, '%s' % message)
    201 progress.__doc__ = Logger.progress.__doc__ 202
    203 -def close():
    204 for logger in _loggers: logger.close()
    205

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.restructuredtext._TermsExtractor-class.html0000644000175000017500000006720310750103050031047 0ustar pronovicpronovic epydoc.markup.restructuredtext._TermsExtractor
    Package epydoc :: Package markup :: Module restructuredtext :: Class _TermsExtractor
    [hide private]
    [frames] | no frames]

    Class _TermsExtractor

    source code


    A docutils node visitor that extracts the terms from documentation.

    Terms are created using the :term: interpreted text role.

    Instance Methods [hide private]
     
    __init__(self, document) source code
    call graph 
     
    visit_document(self, node) source code
    call graph 
     
    visit_emphasis(self, node) source code
    call graph 
     
    depart_emphasis(self, node) source code
    call graph 
     
    visit_Text(self, node) source code
    call graph 
     
    unknown_visit(self, node)
    Ignore all unknown nodes
    source code
    call graph 
     
    unknown_departure(self, node)
    Ignore all unknown nodes
    source code
    call graph 

    Inherited from docutils.nodes.NodeVisitor: dispatch_departure, dispatch_visit

    Class Variables [hide private]

    Inherited from docutils.nodes.NodeVisitor: optional

    Instance Variables [hide private]
    list terms
    The terms currently found.
    Method Details [hide private]

    __init__(self, document)
    (Constructor)

    source code 
    call graph 
    Overrides: docutils.nodes.NodeVisitor.__init__

    unknown_visit(self, node)

    source code 
    call graph 

    Ignore all unknown nodes

    Overrides: docutils.nodes.NodeVisitor.unknown_visit

    unknown_departure(self, node)

    source code 
    call graph 

    Ignore all unknown nodes

    Overrides: docutils.nodes.NodeVisitor.unknown_departure

    epydoc-3.0.1+dfsg/doc/api/term-index.html0000644000175000017500000004047710750103050020460 0ustar pronovicpronovic Term Definition Index
     
    [hide private]
    [frames] | no frames]
    [ Identifiers | Term Definitions | Bugs | To Do ]

    Term Definition Index

    [ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

    B

    C

    D

    E

    F

    I

    J

    L

    M

    O

    P

    R

    S

    T

    U



    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.doctest.XMLDoctestColorizer-class.html0000644000175000017500000004233110750103050027601 0ustar pronovicpronovic epydoc.markup.doctest.XMLDoctestColorizer
    Package epydoc :: Package markup :: Module doctest :: Class XMLDoctestColorizer
    [hide private]
    [frames] | no frames]

    Class XMLDoctestColorizer

    source code


    A subclass of DoctestColorizer that generates XML-like output. This class is mainly intended to be used for testing purposes.

    Instance Methods [hide private]
     
    markup(self, s, tag)
    Apply syntax highlighting to a single substring from a doctest block.
    source code

    Inherited from DoctestColorizer: colorize_codeblock, colorize_doctest, colorize_inline, subfunc

    Class Variables [hide private]
      PREFIX = '<colorized>\n'
    A string that is added to the beginning of the strings returned by colorize_codeblock and colorize_doctest.
      SUFFIX = '</colorized>\n'
    A string that is added to the end of the strings returned by colorize_codeblock and colorize_doctest.

    Inherited from DoctestColorizer: DOCTEST_DIRECTIVE_RE, DOCTEST_EXAMPLE_RE, DOCTEST_RE, EXCEPT_RE, PROMPT2_RE, PROMPT_RE

    Method Details [hide private]

    markup(self, s, tag)

    source code 

    Apply syntax highlighting to a single substring from a doctest block. s is the substring, and tag is the tag that should be applied to the substring. tag will be one of the following strings:

    • prompt -- the Python PS1 prompt (>>>)
    • more -- the Python PS2 prompt (...)
    • keyword -- a Python keyword (for, if, etc.)
    • builtin -- a Python builtin name (abs, dir, etc.)
    • string -- a string literal
    • comment -- a comment
    • except -- an exception traceback (up to the next >>>)
    • output -- the output from a doctest block.
    • defname -- the name of a function or class defined by a def or class statement.
    • other -- anything else (does *not* include output.)
    Overrides: DoctestColorizer.markup
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.log.SimpleLogger-class.html0000644000175000017500000002540110750103050024130 0ustar pronovicpronovic epydoc.log.SimpleLogger
    Package epydoc :: Module log :: Class SimpleLogger
    [hide private]
    [frames] | no frames]

    Class SimpleLogger

    source code


    Instance Methods [hide private]
     
    __init__(self, threshold=30) source code
     
    log(self, level, message)
    Display a message.
    source code

    Inherited from Logger: close, end_block, end_progress, progress, start_block, start_progress

    Method Details [hide private]

    log(self, level, message)

    source code 

    Display a message.

    Parameters:
    • message - The message string to display. message may contain newlines, but does not need to end in a newline.
    • level - An integer value indicating the severity of the message.
    Overrides: Logger.log
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.html_colorize-pysrc.html0000644000175000017500000071345010750103050025675 0ustar pronovicpronovic epydoc.docwriter.html_colorize
    Package epydoc :: Package docwriter :: Module html_colorize
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.docwriter.html_colorize

      1  # 
      2  # epydoc.html: HTML colorizers 
      3  # Edward Loper 
      4  # 
      5  # Created [10/16/02 09:49 PM] 
      6  # $Id: html_colorize.py 1674 2008-01-29 06:03:36Z edloper $ 
      7  # 
      8   
      9  """ 
     10  Functions to produce colorized HTML code for various objects. 
     11  Currently, C{html_colorize} defines functions to colorize 
     12  Python source code. 
     13  """ 
     14  __docformat__ = 'epytext en' 
     15   
     16  import re, codecs 
     17  from epydoc import log 
     18  from epydoc.util import py_src_filename 
     19  from epydoc.apidoc import * 
     20  import tokenize, token, cgi, keyword 
     21  try: from cStringIO import StringIO 
     22  except: from StringIO import StringIO 
     23   
     24  ###################################################################### 
     25  ## Python source colorizer 
     26  ###################################################################### 
     27  """ 
     28  Goals: 
     29    - colorize tokens appropriately (using css) 
     30    - optionally add line numbers 
     31    -  
     32  """ 
     33   
     34  #: Javascript code for the PythonSourceColorizer 
     35  PYSRC_JAVASCRIPTS = '''\ 
     36  function expand(id) { 
     37    var elt = document.getElementById(id+"-expanded"); 
     38    if (elt) elt.style.display = "block"; 
     39    var elt = document.getElementById(id+"-expanded-linenums"); 
     40    if (elt) elt.style.display = "block"; 
     41    var elt = document.getElementById(id+"-collapsed"); 
     42    if (elt) { elt.innerHTML = ""; elt.style.display = "none"; } 
     43    var elt = document.getElementById(id+"-collapsed-linenums"); 
     44    if (elt) { elt.innerHTML = ""; elt.style.display = "none"; } 
     45    var elt = document.getElementById(id+"-toggle"); 
     46    if (elt) { elt.innerHTML = "-"; } 
     47  } 
     48   
     49  function collapse(id) { 
     50    var elt = document.getElementById(id+"-expanded"); 
     51    if (elt) elt.style.display = "none"; 
     52    var elt = document.getElementById(id+"-expanded-linenums"); 
     53    if (elt) elt.style.display = "none"; 
     54    var elt = document.getElementById(id+"-collapsed-linenums"); 
     55    if (elt) { elt.innerHTML = "<br />"; elt.style.display="block"; } 
     56    var elt = document.getElementById(id+"-toggle"); 
     57    if (elt) { elt.innerHTML = "+"; } 
     58    var elt = document.getElementById(id+"-collapsed"); 
     59    if (elt) { 
     60      elt.style.display = "block"; 
     61       
     62      var indent = elt.getAttribute("indent"); 
     63      var pad = elt.getAttribute("pad"); 
     64      var s = "<tt class=\'py-lineno\'>"; 
     65      for (var i=0; i<pad.length; i++) { s += "&nbsp;" } 
     66      s += "</tt>"; 
     67      s += "&nbsp;&nbsp;<tt class=\'py-line\'>"; 
     68      for (var i=0; i<indent.length; i++) { s += "&nbsp;" } 
     69      s += "<a href=\'#\' onclick=\'expand(\\"" + id; 
     70      s += "\\");return false\'>...</a></tt><br />"; 
     71      elt.innerHTML = s; 
     72    } 
     73  } 
     74   
     75  function toggle(id) { 
     76    elt = document.getElementById(id+"-toggle"); 
     77    if (elt.innerHTML == "-") 
     78        collapse(id);  
     79    else 
     80        expand(id); 
     81    return false; 
     82  } 
     83   
     84  function highlight(id) { 
     85    var elt = document.getElementById(id+"-def"); 
     86    if (elt) elt.className = "py-highlight-hdr"; 
     87    var elt = document.getElementById(id+"-expanded"); 
     88    if (elt) elt.className = "py-highlight"; 
     89    var elt = document.getElementById(id+"-collapsed"); 
     90    if (elt) elt.className = "py-highlight"; 
     91  } 
     92   
     93  function num_lines(s) { 
     94    var n = 1; 
     95    var pos = s.indexOf("\\n"); 
     96    while ( pos > 0) { 
     97      n += 1; 
     98      pos = s.indexOf("\\n", pos+1); 
     99    } 
    100    return n; 
    101  } 
    102   
    103  // Collapse all blocks that mave more than `min_lines` lines. 
    104  function collapse_all(min_lines) { 
    105    var elts = document.getElementsByTagName("div"); 
    106    for (var i=0; i<elts.length; i++) { 
    107      var elt = elts[i]; 
    108      var split = elt.id.indexOf("-"); 
    109      if (split > 0) 
    110        if (elt.id.substring(split, elt.id.length) == "-expanded") 
    111          if (num_lines(elt.innerHTML) > min_lines) 
    112            collapse(elt.id.substring(0, split)); 
    113    } 
    114  } 
    115   
    116  function expandto(href) { 
    117    var start = href.indexOf("#")+1; 
    118    if (start != 0 && start != href.length) { 
    119      if (href.substring(start, href.length) != "-") { 
    120        collapse_all(4); 
    121        pos = href.indexOf(".", start); 
    122        while (pos != -1) { 
    123          var id = href.substring(start, pos); 
    124          expand(id); 
    125          pos = href.indexOf(".", pos+1); 
    126        } 
    127        var id = href.substring(start, href.length); 
    128        expand(id); 
    129        highlight(id); 
    130      } 
    131    } 
    132  } 
    133   
    134  function kill_doclink(id) { 
    135    var parent = document.getElementById(id); 
    136    parent.removeChild(parent.childNodes.item(0)); 
    137  } 
    138  function auto_kill_doclink(ev) { 
    139    if (!ev) var ev = window.event; 
    140    if (!this.contains(ev.toElement)) { 
    141      var parent = document.getElementById(this.parentID); 
    142      parent.removeChild(parent.childNodes.item(0)); 
    143    } 
    144  } 
    145   
    146  function doclink(id, name, targets_id) { 
    147    var elt = document.getElementById(id); 
    148   
    149    // If we already opened the box, then destroy it. 
    150    // (This case should never occur, but leave it in just in case.) 
    151    if (elt.childNodes.length > 1) { 
    152      elt.removeChild(elt.childNodes.item(0)); 
    153    } 
    154    else { 
    155      // The outer box: relative + inline positioning. 
    156      var box1 = document.createElement("div"); 
    157      box1.style.position = "relative"; 
    158      box1.style.display = "inline"; 
    159      box1.style.top = 0; 
    160      box1.style.left = 0; 
    161     
    162      // A shadow for fun 
    163      var shadow = document.createElement("div"); 
    164      shadow.style.position = "absolute"; 
    165      shadow.style.left = "-1.3em"; 
    166      shadow.style.top = "-1.3em"; 
    167      shadow.style.background = "#404040"; 
    168       
    169      // The inner box: absolute positioning. 
    170      var box2 = document.createElement("div"); 
    171      box2.style.position = "relative"; 
    172      box2.style.border = "1px solid #a0a0a0"; 
    173      box2.style.left = "-.2em"; 
    174      box2.style.top = "-.2em"; 
    175      box2.style.background = "white"; 
    176      box2.style.padding = ".3em .4em .3em .4em"; 
    177      box2.style.fontStyle = "normal"; 
    178      box2.onmouseout=auto_kill_doclink; 
    179      box2.parentID = id; 
    180   
    181      // Get the targets 
    182      var targets_elt = document.getElementById(targets_id); 
    183      var targets = targets_elt.getAttribute("targets"); 
    184      var links = ""; 
    185      target_list = targets.split(","); 
    186      for (var i=0; i<target_list.length; i++) { 
    187          var target = target_list[i].split("="); 
    188          links += "<li><a href=\'" + target[1] +  
    189                 "\' style=\'text-decoration:none\'>" + 
    190                 target[0] + "</a></li>"; 
    191      } 
    192     
    193      // Put it all together. 
    194      elt.insertBefore(box1, elt.childNodes.item(0)); 
    195      //box1.appendChild(box2); 
    196      box1.appendChild(shadow); 
    197      shadow.appendChild(box2); 
    198      box2.innerHTML = 
    199          "Which <b>"+name+"</b> do you want to see documentation for?" + 
    200          "<ul style=\'margin-bottom: 0;\'>" + 
    201          links +  
    202          "<li><a href=\'#\' style=\'text-decoration:none\' " + 
    203          "onclick=\'kill_doclink(\\""+id+"\\");return false;\'>"+ 
    204          "<i>None of the above</i></a></li></ul>"; 
    205    } 
    206    return false; 
    207  } 
    208  ''' 
    209   
    210  PYSRC_EXPANDTO_JAVASCRIPT = '''\ 
    211  <script type="text/javascript"> 
    212  <!-- 
    213  expandto(location.href); 
    214  // --> 
    215  </script> 
    216  ''' 
    217   
    
    219 """ 220 A class that renders a python module's source code into HTML 221 pages. These HTML pages are intended to be provided along with 222 the API documentation for a module, in case a user wants to learn 223 more about a particular object by examining its source code. 224 Links are therefore generated from the API documentation to the 225 source code pages, and from the source code pages back into the 226 API documentation. 227 228 The HTML generated by C{PythonSourceColorizer} has several notable 229 features: 230 231 - CSS styles are used to color tokens according to their type. 232 (See L{CSS_CLASSES} for a list of the different token types 233 that are identified). 234 235 - Line numbers are included to the left of each line. 236 237 - The first line of each class and function definition includes 238 a link to the API source documentation for that object. 239 240 - The first line of each class and function definition includes 241 an anchor that can be used to link directly to that class or 242 function. 243 244 - If javascript is enabled, and the page is loaded using the 245 anchor for a class or function (i.e., if the url ends in 246 C{'#I{<name>}'}), then that class or function will automatically 247 be highlighted; and all other classes and function definition 248 blocks will be 'collapsed'. These collapsed blocks can be 249 expanded by clicking on them. 250 251 - Unicode input is supported (including automatic detection 252 of C{'coding:'} declarations). 253 254 """ 255 #: A look-up table that is used to determine which CSS class 256 #: should be used to colorize a given token. The following keys 257 #: may be used: 258 #: - Any token name (e.g., C{'STRING'}) 259 #: - Any operator token (e.g., C{'='} or C{'@'}). 260 #: - C{'KEYWORD'} -- Python keywords such as C{'for'} and C{'if'} 261 #: - C{'DEFNAME'} -- the name of a class or function at the top 262 #: of its definition statement. 263 #: - C{'BASECLASS'} -- names of base classes at the top of a class 264 #: definition statement. 265 #: - C{'PARAM'} -- function parameters 266 #: - C{'DOCSTRING'} -- docstrings 267 #: - C{'DECORATOR'} -- decorator names 268 #: If no CSS class can be found for a given token, then it won't 269 #: be marked with any CSS class. 270 CSS_CLASSES = { 271 'NUMBER': 'py-number', 272 'STRING': 'py-string', 273 'COMMENT': 'py-comment', 274 'NAME': 'py-name', 275 'KEYWORD': 'py-keyword', 276 'DEFNAME': 'py-def-name', 277 'BASECLASS': 'py-base-class', 278 'PARAM': 'py-param', 279 'DOCSTRING': 'py-docstring', 280 'DECORATOR': 'py-decorator', 281 'OP': 'py-op', 282 '@': 'py-decorator', 283 } 284 285 #: HTML code for the beginning of a collapsable function or class 286 #: definition block. The block contains two <div>...</div> 287 #: elements -- a collapsed version and an expanded version -- and 288 #: only one of these elements is visible at any given time. By 289 #: default, all definition blocks are expanded. 290 #: 291 #: This string should be interpolated with the following values:: 292 #: (name, indentation, name) 293 #: Where C{name} is the anchor name for the function or class; and 294 #: indentation is a string of whitespace used to indent the 295 #: ellipsis marker in the collapsed version. 296 START_DEF_BLOCK = ( 297 '<div id="%s-collapsed" style="display:none;" ' 298 'pad="%s" indent="%s"></div>' 299 '<div id="%s-expanded">') 300 301 #: HTML code for the end of a collapsable function or class 302 #: definition block. 303 END_DEF_BLOCK = '</div>' 304 305 #: A regular expression used to pick out the unicode encoding for 306 #: the source file. 307 UNICODE_CODING_RE = re.compile(r'.*?\n?.*?coding[:=]\s*([-\w.]+)') 308 309 #: A configuration constant, used to determine whether or not to add 310 #: collapsable <div> elements for definition blocks. 311 ADD_DEF_BLOCKS = True 312 313 #: A configuration constant, used to determine whether or not to 314 #: add line numbers. 315 ADD_LINE_NUMBERS = True 316 317 #: A configuration constant, used to determine whether or not to 318 #: add tooltips for linked names. 319 ADD_TOOLTIPS = True 320 321 #: If true, then try to guess which target is appropriate for 322 #: linked names; if false, then always open a div asking the 323 #: user which one they want. 324 GUESS_LINK_TARGETS = False 325
    326 - def __init__(self, module_filename, module_name, 327 docindex=None, url_func=None, name_to_docs=None, 328 tab_width=8):
    329 """ 330 Create a new HTML colorizer for the specified module. 331 332 @param module_filename: The name of the file containing the 333 module; its text will be loaded from this file. 334 @param module_name: The dotted name of the module; this will 335 be used to create links back into the API source 336 documentation. 337 """ 338 # Get the source version, if possible. 339 try: module_filename = py_src_filename(module_filename) 340 except: pass 341 342 #: The filename of the module we're colorizing. 343 self.module_filename = module_filename 344 345 #: The dotted name of the module we're colorizing. 346 self.module_name = module_name 347 348 #: A docindex, used to create href links from identifiers to 349 #: the API documentation for their values. 350 self.docindex = docindex 351 352 #: A mapping from short names to lists of ValueDoc, used to 353 #: decide which values an identifier might map to when creating 354 #: href links from identifiers to the API docs for their values. 355 self.name_to_docs = name_to_docs 356 357 #: A function that maps APIDoc -> URL, used to create href 358 #: links from identifiers to the API documentation for their 359 #: values. 360 self.url_func = url_func 361 362 #: The index in C{text} of the last character of the last 363 #: token we've processed. 364 self.pos = 0 365 366 #: A list that maps line numbers to character offsets in 367 #: C{text}. In particular, line C{M{i}} begins at character 368 #: C{line_offset[i]} in C{text}. Since line numbers begin at 369 #: 1, the first element of C{line_offsets} is C{None}. 370 self.line_offsets = [] 371 372 #: A list of C{(toktype, toktext)} for all tokens on the 373 #: logical line that we are currently processing. Once a 374 #: complete line of tokens has been collected in C{cur_line}, 375 #: it is sent to L{handle_line} for processing. 376 self.cur_line = [] 377 378 #: A list of the names of the class or functions that include 379 #: the current block. C{context} has one element for each 380 #: level of indentation; C{context[i]} is the name of the class 381 #: or function defined by the C{i}th level of indentation, or 382 #: C{None} if that level of indentation doesn't correspond to a 383 #: class or function definition. 384 self.context = [] 385 386 #: A list, corresponding one-to-one with L{self.context}, 387 #: indicating the type of each entry. Each element of 388 #: C{context_types} is one of: C{'func'}, C{'class'}, C{None}. 389 self.context_types = [] 390 391 #: A list of indentation strings for each of the current 392 #: block's indents. I.e., the current total indentation can 393 #: be found by taking C{''.join(self.indents)}. 394 self.indents = [] 395 396 #: The line number of the line we're currently processing. 397 self.lineno = 0 398 399 #: The name of the class or function whose definition started 400 #: on the previous logical line, or C{None} if the previous 401 #: logical line was not a class or function definition. 402 self.def_name = None 403 404 #: The type of the class or function whose definition started 405 #: on the previous logical line, or C{None} if the previous 406 #: logical line was not a class or function definition. 407 #: Can be C{'func'}, C{'class'}, C{None}. 408 self.def_type = None 409 410 #: The number of spaces to replace each tab in source code with 411 self.tab_width = tab_width
    412 413
    414 - def find_line_offsets(self):
    415 """ 416 Construct the L{line_offsets} table from C{self.text}. 417 """ 418 # line 0 doesn't exist; line 1 starts at char offset 0. 419 self.line_offsets = [None, 0] 420 # Find all newlines in `text`, and add an entry to 421 # line_offsets for each one. 422 pos = self.text.find('\n') 423 while pos != -1: 424 self.line_offsets.append(pos+1) 425 pos = self.text.find('\n', pos+1) 426 # Add a final entry, marking the end of the string. 427 self.line_offsets.append(len(self.text))
    428
    429 - def lineno_to_html(self):
    430 template = '%%%ds' % self.linenum_size 431 n = template % self.lineno 432 return '<a name="L%s"></a><tt class="py-lineno">%s</tt>' \ 433 % (self.lineno, n)
    434
    435 - def colorize(self):
    436 """ 437 Return an HTML string that renders the source code for the 438 module that was specified in the constructor. 439 """ 440 # Initialize all our state variables 441 self.pos = 0 442 self.cur_line = [] 443 self.context = [] 444 self.context_types = [] 445 self.indents = [] 446 self.lineno = 1 447 self.def_name = None 448 self.def_type = None 449 self.has_decorators = False 450 451 # Cache, used so we only need to list the target elements once 452 # for each variable. 453 self.doclink_targets_cache = {} 454 455 # Load the module's text. 456 self.text = open(self.module_filename).read() 457 self.text = self.text.expandtabs(self.tab_width).rstrip()+'\n' 458 459 # Construct the line_offsets table. 460 self.find_line_offsets() 461 462 num_lines = self.text.count('\n')+1 463 self.linenum_size = len(`num_lines+1`) 464 465 # Call the tokenizer, and send tokens to our `tokeneater()` 466 # method. If anything goes wrong, then fall-back to using 467 # the input text as-is (with no colorization). 468 try: 469 output = StringIO() 470 self.out = output.write 471 tokenize.tokenize(StringIO(self.text).readline, self.tokeneater) 472 html = output.getvalue() 473 if self.has_decorators: 474 html = self._FIX_DECORATOR_RE.sub(r'\2\1', html) 475 except tokenize.TokenError, ex: 476 html = self.text 477 478 # Check for a unicode encoding declaration. 479 m = self.UNICODE_CODING_RE.match(self.text) 480 if m: coding = m.group(1) 481 else: coding = 'iso-8859-1' 482 483 # Decode the html string into unicode, and then encode it back 484 # into ascii, replacing any non-ascii characters with xml 485 # character references. 486 try: 487 html = html.decode(coding).encode('ascii', 'xmlcharrefreplace') 488 except LookupError: 489 coding = 'iso-8859-1' 490 html = html.decode(coding).encode('ascii', 'xmlcharrefreplace') 491 492 # Call expandto. 493 html += PYSRC_EXPANDTO_JAVASCRIPT 494 495 return html
    496
    497 - def tokeneater(self, toktype, toktext, (srow,scol), (erow,ecol), line):
    498 """ 499 A callback function used by C{tokenize.tokenize} to handle 500 each token in the module. C{tokeneater} collects tokens into 501 the C{self.cur_line} list until a complete logical line has 502 been formed; and then calls L{handle_line} to process that line. 503 """ 504 # If we encounter any errors, then just give up. 505 if toktype == token.ERRORTOKEN: 506 raise tokenize.TokenError, toktype 507 508 # Did we skip anything whitespace? If so, add a pseudotoken 509 # for it, with toktype=None. (Note -- this skipped string 510 # might also contain continuation slashes; but I won't bother 511 # to colorize them.) 512 startpos = self.line_offsets[srow] + scol 513 if startpos > self.pos: 514 skipped = self.text[self.pos:startpos] 515 self.cur_line.append( (None, skipped) ) 516 517 # Update our position. 518 self.pos = startpos + len(toktext) 519 520 # Update our current line. 521 self.cur_line.append( (toktype, toktext) ) 522 523 # When we reach the end of a line, process it. 524 if toktype == token.NEWLINE or toktype == token.ENDMARKER: 525 self.handle_line(self.cur_line) 526 self.cur_line = []
    527 528 _next_uid = 0 529 530 # [xx] note -- this works with byte strings, not unicode strings! 531 # I may change it to use unicode eventually, but when I do it 532 # needs to be changed all at once.
    533 - def handle_line(self, line):
    534 """ 535 Render a single logical line from the module, and write the 536 generated HTML to C{self.out}. 537 538 @param line: A single logical line, encoded as a list of 539 C{(toktype,tokttext)} pairs corresponding to the tokens in 540 the line. 541 """ 542 # def_name is the name of the function or class defined by 543 # this line; or None if no funciton or class is defined. 544 def_name = None 545 546 # def_type is the type of the function or class defined by 547 # this line; or None if no funciton or class is defined. 548 def_type = None 549 550 # does this line start a class/func def? 551 starting_def_block = False 552 553 in_base_list = False 554 in_param_list = False 555 in_param_default = 0 556 at_module_top = (self.lineno == 1) 557 558 ended_def_blocks = 0 559 560 # The html output. 561 if self.ADD_LINE_NUMBERS: 562 s = self.lineno_to_html() 563 self.lineno += 1 564 else: 565 s = '' 566 s += ' <tt class="py-line">' 567 568 # Loop through each token, and colorize it appropriately. 569 for i, (toktype, toktext) in enumerate(line): 570 if type(s) is not str: 571 if type(s) is unicode: 572 log.error('While colorizing %s -- got unexpected ' 573 'unicode string' % self.module_name) 574 s = s.encode('ascii', 'xmlcharrefreplace') 575 else: 576 raise ValueError('Unexpected value for s -- %s' % 577 type(s).__name__) 578 579 # For each token, determine its css class and whether it 580 # should link to a url. 581 css_class = None 582 url = None 583 tooltip = None 584 onclick = uid = targets = None # these 3 are used together. 585 586 # Is this token the class name in a class definition? If 587 # so, then make it a link back into the API docs. 588 if i>=2 and line[i-2][1] == 'class': 589 in_base_list = True 590 css_class = self.CSS_CLASSES['DEFNAME'] 591 def_name = toktext 592 def_type = 'class' 593 if 'func' not in self.context_types: 594 cls_name = self.context_name(def_name) 595 url = self.name2url(cls_name) 596 s = self.mark_def(s, cls_name) 597 starting_def_block = True 598 599 # Is this token the function name in a function def? If 600 # so, then make it a link back into the API docs. 601 elif i>=2 and line[i-2][1] == 'def': 602 in_param_list = True 603 css_class = self.CSS_CLASSES['DEFNAME'] 604 def_name = toktext 605 def_type = 'func' 606 if 'func' not in self.context_types: 607 cls_name = self.context_name() 608 func_name = self.context_name(def_name) 609 url = self.name2url(cls_name, def_name) 610 s = self.mark_def(s, func_name) 611 starting_def_block = True 612 613 # For each indent, update the indents list (which we use 614 # to keep track of indentation strings) and the context 615 # list. If this indent is the start of a class or 616 # function def block, then self.def_name will be its name; 617 # otherwise, it will be None. 618 elif toktype == token.INDENT: 619 self.indents.append(toktext) 620 self.context.append(self.def_name) 621 self.context_types.append(self.def_type) 622 623 # When we dedent, pop the last elements off the indents 624 # list and the context list. If the last context element 625 # is a name, then we're ending a class or function def 626 # block; so write an end-div tag. 627 elif toktype == token.DEDENT: 628 self.indents.pop() 629 self.context_types.pop() 630 if self.context.pop(): 631 ended_def_blocks += 1 632 633 # If this token contains whitespace, then don't bother to 634 # give it a css tag. 635 elif toktype in (None, tokenize.NL, token.NEWLINE, 636 token.ENDMARKER): 637 css_class = None 638 639 # Check if the token is a keyword. 640 elif toktype == token.NAME and keyword.iskeyword(toktext): 641 css_class = self.CSS_CLASSES['KEYWORD'] 642 643 elif in_base_list and toktype == token.NAME: 644 css_class = self.CSS_CLASSES['BASECLASS'] 645 646 elif (in_param_list and toktype == token.NAME and 647 not in_param_default): 648 css_class = self.CSS_CLASSES['PARAM'] 649 650 # Class/function docstring. 651 elif (self.def_name and line[i-1][0] == token.INDENT and 652 self.is_docstring(line, i)): 653 css_class = self.CSS_CLASSES['DOCSTRING'] 654 655 # Module docstring. 656 elif at_module_top and self.is_docstring(line, i): 657 css_class = self.CSS_CLASSES['DOCSTRING'] 658 659 # check for decorators?? 660 elif (toktype == token.NAME and 661 ((i>0 and line[i-1][1]=='@') or 662 (i>1 and line[i-1][0]==None and line[i-2][1] == '@'))): 663 css_class = self.CSS_CLASSES['DECORATOR'] 664 self.has_decorators = True 665 666 # If it's a name, try to link it. 667 elif toktype == token.NAME: 668 css_class = self.CSS_CLASSES['NAME'] 669 # If we have a variable named `toktext` in the current 670 # context, then link to that. Note that if we're inside 671 # a function, then that function is our context, not 672 # the namespace that contains it. [xx] this isn't always 673 # the right thing to do. 674 if (self.GUESS_LINK_TARGETS and self.docindex is not None 675 and self.url_func is not None): 676 context = [n for n in self.context if n is not None] 677 container = self.docindex.get_vardoc( 678 DottedName(self.module_name, *context)) 679 if isinstance(container, NamespaceDoc): 680 doc = container.variables.get(toktext) 681 if doc is not None: 682 url = self.url_func(doc) 683 tooltip = str(doc.canonical_name) 684 # Otherwise, check the name_to_docs index to see what 685 # else this name might refer to. 686 if (url is None and self.name_to_docs is not None 687 and self.url_func is not None): 688 docs = self.name_to_docs.get(toktext) 689 if docs: 690 tooltip='\n'.join([str(d.canonical_name) 691 for d in docs]) 692 if len(docs) == 1 and self.GUESS_LINK_TARGETS: 693 url = self.url_func(docs[0]) 694 else: 695 uid, onclick, targets = self.doclink(toktext, docs) 696 697 # For all other tokens, look up the CSS class to use 698 # based on the token's type. 699 else: 700 if toktype == token.OP and toktext in self.CSS_CLASSES: 701 css_class = self.CSS_CLASSES[toktext] 702 elif token.tok_name[toktype] in self.CSS_CLASSES: 703 css_class = self.CSS_CLASSES[token.tok_name[toktype]] 704 else: 705 css_class = None 706 707 # update our status.. 708 if toktext == ':': 709 in_base_list = False 710 in_param_list = False 711 if toktext == '=' and in_param_list: 712 in_param_default = True 713 if in_param_default: 714 if toktext in ('(','[','{'): in_param_default += 1 715 if toktext in (')',']','}'): in_param_default -= 1 716 if toktext == ',' and in_param_default == 1: 717 in_param_default = 0 718 719 # Write this token, with appropriate colorization. 720 if tooltip and self.ADD_TOOLTIPS: 721 tooltip_html = ' title="%s"' % tooltip 722 else: tooltip_html = '' 723 if css_class: css_class_html = ' class="%s"' % css_class 724 else: css_class_html = '' 725 if onclick: 726 if targets: targets_html = ' targets="%s"' % targets 727 else: targets_html = '' 728 s += ('<tt id="%s"%s%s><a%s%s href="#" onclick="%s">' % 729 (uid, css_class_html, targets_html, tooltip_html, 730 css_class_html, onclick)) 731 elif url: 732 if isinstance(url, unicode): 733 url = url.encode('ascii', 'xmlcharrefreplace') 734 s += ('<a%s%s href="%s">' % 735 (tooltip_html, css_class_html, url)) 736 elif css_class_html or tooltip_html: 737 s += '<tt%s%s>' % (tooltip_html, css_class_html) 738 if i == len(line)-1: 739 s += ' </tt>' # Closes <tt class="py-line"> 740 s += cgi.escape(toktext) 741 else: 742 try: 743 s += self.add_line_numbers(cgi.escape(toktext), css_class) 744 except Exception, e: 745 print (toktext, css_class, toktext.encode('ascii')) 746 raise 747 748 if onclick: s += "</a></tt>" 749 elif url: s += '</a>' 750 elif css_class_html or tooltip_html: s += '</tt>' 751 752 if self.ADD_DEF_BLOCKS: 753 for i in range(ended_def_blocks): 754 self.out(self.END_DEF_BLOCK) 755 756 # Strip any empty <tt>s. 757 s = re.sub(r'<tt class="[\w+]"></tt>', '', s) 758 759 # Write the line. 760 self.out(s) 761 762 if def_name and starting_def_block: 763 self.out('</div>') 764 765 # Add div's if we're starting a def block. 766 if (self.ADD_DEF_BLOCKS and def_name and starting_def_block and 767 (line[-2][1] == ':')): 768 indentation = (''.join(self.indents)+' ').replace(' ', '+') 769 linenum_padding = '+'*self.linenum_size 770 name=self.context_name(def_name) 771 self.out(self.START_DEF_BLOCK % (name, linenum_padding, 772 indentation, name)) 773 774 self.def_name = def_name 775 self.def_type = def_type
    776
    777 - def context_name(self, extra=None):
    778 pieces = [n for n in self.context if n is not None] 779 if extra is not None: pieces.append(extra) 780 return '.'.join(pieces)
    781 802
    803 - def doc_descr(self, doc, context):
    804 name = str(doc.canonical_name) 805 descr = '%s %s' % (self.doc_kind(doc), name) 806 if isinstance(doc, RoutineDoc): 807 descr += '()' 808 return descr
    809 810 # [XX] copied streight from html.py; this should be consolidated, 811 # probably into apidoc.
    812 - def doc_kind(self, doc):
    813 if isinstance(doc, ModuleDoc) and doc.is_package == True: 814 return 'Package' 815 elif (isinstance(doc, ModuleDoc) and 816 doc.canonical_name[0].startswith('script')): 817 return 'Script' 818 elif isinstance(doc, ModuleDoc): 819 return 'Module' 820 elif isinstance(doc, ClassDoc): 821 return 'Class' 822 elif isinstance(doc, ClassMethodDoc): 823 return 'Class Method' 824 elif isinstance(doc, StaticMethodDoc): 825 return 'Static Method' 826 elif isinstance(doc, RoutineDoc): 827 if (self.docindex is not None and 828 isinstance(self.docindex.container(doc), ClassDoc)): 829 return 'Method' 830 else: 831 return 'Function' 832 else: 833 return 'Variable'
    834
    835 - def mark_def(self, s, name):
    836 replacement = ('<a name="%s"></a><div id="%s-def">\\1' 837 '<a class="py-toggle" href="#" id="%s-toggle" ' 838 'onclick="return toggle(\'%s\');">-</a>\\2' % 839 (name, name, name, name)) 840 return re.sub('(.*) (<tt class="py-line">.*)\Z', replacement, s)
    841
    842 - def is_docstring(self, line, i):
    843 if line[i][0] != token.STRING: return False 844 for toktype, toktext in line[i:]: 845 if toktype not in (token.NEWLINE, tokenize.COMMENT, 846 tokenize.NL, token.STRING, None): 847 return False 848 return True
    849
    850 - def add_line_numbers(self, s, css_class):
    851 result = '' 852 start = 0 853 end = s.find('\n')+1 854 while end: 855 result += s[start:end-1] 856 if css_class: result += '</tt>' 857 result += ' </tt>' # py-line 858 result += '\n' 859 if self.ADD_LINE_NUMBERS: 860 result += self.lineno_to_html() 861 result += ' <tt class="py-line">' 862 if css_class: result += '<tt class="%s">' % css_class 863 start = end 864 end = s.find('\n', end)+1 865 self.lineno += 1 866 result += s[start:] 867 return result
    868
    869 - def name2url(self, class_name, func_name=None):
    870 if class_name: 871 class_name = '%s.%s' % (self.module_name, class_name) 872 if func_name: 873 return '%s-class.html#%s' % (class_name, func_name) 874 else: 875 return '%s-class.html' % class_name 876 else: 877 return '%s-module.html#%s' % (self.module_name, func_name)
    878 879 #: A regexp used to move the <div> that marks the beginning of a 880 #: function or method to just before the decorators. 881 _FIX_DECORATOR_RE = re.compile( 882 r'((?:^<a name="L\d+"></a><tt class="py-lineno">\s*\d+</tt>' 883 r'\s*<tt class="py-line">(?:<tt class="py-decorator">.*|\s*</tt>|' 884 r'\s*<tt class="py-comment">.*)\n)+)' 885 r'(<a name="\w+"></a><div id="\w+-def">)', re.MULTILINE)
    886 887 _HDR = '''\ 888 <?xml version="1.0" encoding="ascii"?> 889 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 890 "DTD/xhtml1-transitional.dtd"> 891 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 892 <head> 893 <title>$title$</title> 894 <link rel="stylesheet" href="epydoc.css" type="text/css" /> 895 <script type="text/javascript" src="epydoc.js"></script> 896 </head> 897 898 <body bgcolor="white" text="black" link="blue" vlink="#204080" 899 alink="#204080"> 900 ''' 901 _FOOT = '</body></html>' 902 if __name__=='__main__': 903 #s = PythonSourceColorizer('../apidoc.py', 'epydoc.apidoc').colorize() 904 s = PythonSourceColorizer('/tmp/fo.py', 'epydoc.apidoc').colorize() 905 #print s 906 import codecs 907 f = codecs.open('/home/edloper/public_html/color3.html', 'w', 'ascii', 'xmlcharrefreplace') 908 f.write(_HDR+'<pre id="py-src-top" class="py-src">'+s+'</pre>'+_FOOT) 909 f.close() 910

    epydoc-3.0.1+dfsg/doc/api/epydoc.test.util-module.html0000644000175000017500000006166210750103050023103 0ustar pronovicpronovic epydoc.test.util
    Package epydoc :: Package test :: Module util
    [hide private]
    [frames] | no frames]

    Module util

    source code

    Utility functions used by the regression tests (*.doctest).

    Functions [hide private]
        Test Functions
     
    buildvaluedoc(s)
    This test function takes a string containing the contents of a module.
    source code
     
    runbuilder(s, attribs='', build=None, exclude='')
    This test function takes a string containing the contents of a module.
    source code
     
    runparser(s, attribs='', show=None, exclude='')
    This test function takes a string containing the contents of a module, and writes it to a file, uses `parse_docs` to parse it, and pretty prints the resulting ModuleDoc object.
    source code
     
    runintrospecter(s, attribs='', introspect=None, exclude='')
    This test function takes a string containing the contents of a module.
    source code
     
    print_warnings()
    Register a logger that will print warnings & errors.
    source code
     
    testencoding(s, introspect=True, parse=True, debug=False)
    An end-to-end test for unicode encodings.
    source code
        Helper Functions
     
    write_pystring_to_tmp_dir(s) source code
     
    cleanup_tmp_dir(tmp_dir) source code
     
    to_plain(docstring)
    Conver a parsed docstring into plain text
    source code
     
    fun_to_plain(val_doc)
    Convert parsed docstrings in text from a RoutineDoc
    source code
     
    print_docstring_as_html(self, parsed_docstring, *varargs, **kwargs)
    Convert the given parsed_docstring to HTML and print it.
    source code
     
    remove_surrogates(s)
    The following is a helper function, used to convert two-character surrogate sequences into single characters.
    source code
    Function Details [hide private]

    buildvaluedoc(s)

    source code 

    This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses build_doc to build documentation, and returns it as a ValueDoc object.

    runbuilder(s, attribs='', build=None, exclude='')

    source code 

    This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses build_doc to build documentation, and pretty prints the resulting ModuleDoc object. The attribs argument specifies which attributes of the APIDocs should be displayed. The build argument gives the name of a variable in the module whose documentation should be built, instead of bilding docs for the whole module.

    runparser(s, attribs='', show=None, exclude='')

    source code 

    This test function takes a string containing the contents of a module, and writes it to a file, uses `parse_docs` to parse it, and pretty prints the resulting ModuleDoc object. The `attribs` argument specifies which attributes of the `APIDoc`s should be displayed. The `show` argument, if specifies, gives the name of the object in the module that should be displayed (but the whole module will always be inspected; this just selects what to display).

    runintrospecter(s, attribs='', introspect=None, exclude='')

    source code 

    This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses introspect_docs to introspect it, and pretty prints the resulting ModuleDoc object. The attribs argument specifies which attributes of the APIDocs should be displayed. The introspect argument gives the name of a variable in the module whose value should be introspected, instead of introspecting the whole module.

    testencoding(s, introspect=True, parse=True, debug=False)

    source code 

    An end-to-end test for unicode encodings. This function takes a given string, writes it to a python file, and processes that file's documentation. It then generates HTML output from the documentation, extracts all docstrings from the generated HTML output, and displays them. (In order to extract & display all docstrings, it monkey-patches the HMTLwriter.docstring_to_html() method.)

    print_docstring_as_html(self, parsed_docstring, *varargs, **kwargs)

    source code 

    Convert the given parsed_docstring to HTML and print it. Ignore any other arguments. This function is used by testencoding to monkey-patch the HTMLWriter class's docstring_to_html() method.

    remove_surrogates(s)

    source code 

    The following is a helper function, used to convert two-character surrogate sequences into single characters. This is needed because some systems create surrogates but others don't.


    epydoc-3.0.1+dfsg/doc/api/epydoc.apidoc.DottedName-class.html0000644000175000017500000026221610750103050024250 0ustar pronovicpronovic epydoc.apidoc.DottedName
    Package epydoc :: Module apidoc :: Class DottedName
    [hide private]
    [frames] | no frames]

    Class DottedName

    source code

    A sequence of identifiers, separated by periods, used to name a Python variable, value, or argument. The identifiers that make up a dotted name can be accessed using the indexing operator:

    >>> name = DottedName('epydoc', 'api_doc', 'DottedName')
    >>> print name
    epydoc.apidoc.DottedName
    >>> name[1]
    'api_doc'
    Nested Classes [hide private]
      InvalidDottedName
    An exception raised by the DottedName constructor when one of its arguments is not a valid dotted name.
    Instance Methods [hide private]
     
    __init__(self, *pieces, **options)
    Construct a new dotted name from the given sequence of pieces, each of which can be either a string or a DottedName.
    source code
    call graph 
     
    __repr__(self) source code
     
    __str__(self)
    Return the dotted name as a string formed by joining its identifiers with periods:
    source code
    call graph 
     
    __add__(self, other)
    Return a new DottedName whose identifier sequence is formed by adding other's identifier sequence to self's.
    source code
    call graph 
     
    __radd__(self, other)
    Return a new DottedName whose identifier sequence is formed by adding self's identifier sequence to other's.
    source code
    call graph 
     
    __getitem__(self, i)
    Return the ith identifier in this DottedName.
    source code
    call graph 
     
    __hash__(self) source code
    call graph 
     
    __cmp__(self, other)
    Compare this dotted name to other.
    source code
    call graph 
     
    __len__(self)
    Return the number of identifiers in this dotted name.
    source code
    call graph 
     
    container(self)
    Return the DottedName formed by removing the last identifier from this dotted name's identifier sequence.
    source code
    call graph 
     
    dominates(self, name, strict=False)
    Return true if this dotted name is equal to a prefix of name.
    source code
    call graph 
    DottedName
    contextualize(self, context)
    If self and context share a common ancestor, then return a name for self, relative to that ancestor.
    source code
    call graph 
    Class Variables [hide private]
      UNREACHABLE = '??'
      _IDENTIFIER_RE = re.compile(r'(?x)(\?\?|(script-)?\w+\'?)(-\d+...
      _ok_identifiers = set(['??', '??-1', '??-10', '??-11', '??-12'...
    A cache of identifier strings that have been checked against _IDENTIFIER_RE and found to be acceptable.
    Method Details [hide private]

    __init__(self, *pieces, **options)
    (Constructor)

    source code 
    call graph 

    Construct a new dotted name from the given sequence of pieces, each of which can be either a string or a DottedName. Each piece is divided into a sequence of identifiers, and these sequences are combined together (in order) to form the identifier sequence for the new DottedName. If a piece contains a string, then it is divided into substrings by splitting on periods, and each substring is checked to see if it is a valid identifier.

    As an optimization, pieces may also contain a single tuple of values. In that case, that tuple will be used as the DottedName's identifiers; it will not be checked to see if it's valid.

    Parameters:

    __str__(self)
    (Informal representation operator)

    source code 
    call graph 

    Return the dotted name as a string formed by joining its identifiers with periods:

    >>> print DottedName('epydoc', 'api_doc', DottedName')
    epydoc.apidoc.DottedName

    __getitem__(self, i)
    (Indexing operator)

    source code 
    call graph 

    Return the ith identifier in this DottedName. If i is a non-empty slice, then return a DottedName built from the identifiers selected by the slice. If i is an empty slice, return an empty list (since empty DottedNames are not valid).

    __cmp__(self, other)
    (Comparison operator)

    source code 
    call graph 

    Compare this dotted name to other. Two dotted names are considered equal if their identifier subsequences are equal. Ordering between dotted names is lexicographic, in order of identifier from left to right.

    container(self)

    source code 
    call graph 

    Return the DottedName formed by removing the last identifier from this dotted name's identifier sequence. If this dotted name only has one name in its identifier sequence, return None instead.

    dominates(self, name, strict=False)

    source code 
    call graph 

    Return true if this dotted name is equal to a prefix of name. If strict is true, then also require that self!=name.

    >>> DottedName('a.b').dominates(DottedName('a.b.c.d'))
    True

    contextualize(self, context)

    source code 
    call graph 

    If self and context share a common ancestor, then return a name for self, relative to that ancestor. If they do not share a common ancestor (or if context is UNKNOWN), then simply return self.

    This is used to generate shorter versions of dotted names in cases where users can infer the intended target from the context.

    Parameters:
    Returns: DottedName

    Class Variable Details [hide private]

    _IDENTIFIER_RE

    Value:
    re.compile(r'(?x)(\?\?|(script-)?\w+\'?)(-\d+)?$')
    

    _ok_identifiers

    A cache of identifier strings that have been checked against _IDENTIFIER_RE and found to be acceptable.

    Value:
    set(['??',
         '??-1',
         '??-10',
         '??-11',
         '??-12',
         '??-13',
         '??-2',
         '??-3',
    ...
    

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.latex-module.html0000644000175000017500000001264710750103050024265 0ustar pronovicpronovic epydoc.docwriter.latex
    Package epydoc :: Package docwriter :: Module latex
    [hide private]
    [frames] | no frames]

    Module latex

    source code

    The LaTeX output generator for epydoc. The main interface provided by this module is the LatexWriter class.


    To Do: Inheritance=listed

    Classes [hide private]
      LatexWriter
    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext.Token-class.html0000644000175000017500000006774410750103050025056 0ustar pronovicpronovic epydoc.markup.epytext.Token
    Package epydoc :: Package markup :: Module epytext :: Class Token
    [hide private]
    [frames] | no frames]

    Class Token

    source code

    Tokens are an intermediate data structure used while constructing the structuring DOM tree for a formatted docstring. There are five types of Token:

    • Paragraphs
    • Literal blocks
    • Doctest blocks
    • Headings
    • Bullets

    The text contained in each Token is stored in the contents variable. The string in this variable has been normalized. For paragraphs, this means that it has been converted into a single line of text, with newline/indentation replaced by single spaces. For literal blocks and doctest blocks, this means that the appropriate amount of leading whitespace has been removed from each line.

    Each Token has an indentation level associated with it, stored in the indent variable. This indentation level is used by the structuring procedure to assemble hierarchical blocks.

    Instance Methods [hide private]
     
    __init__(self, tag, startline, contents, indent, level=None, inline=False)
    Create a new Token.
    source code
    call graph 
    string
    __repr__(self)
    Returns: the formal representation of this Token.
    source code
    Element
    to_dom(self, doc)
    Returns: a DOM representation of this Token.
    source code
    call graph 
    Class Variables [hide private]
    string PARA = 'para'
    The tag value for paragraph Tokens.
    string LBLOCK = 'literalblock'
    The tag value for literal Tokens.
    string DTBLOCK = 'doctestblock'
    The tag value for doctest Tokens.
    string HEADING = 'heading'
    The tag value for heading Tokens.
    string BULLET = 'bullet'
    The tag value for bullet Tokens.
    Instance Variables [hide private]
    string contents
    The normalized text contained in this Token.
    int or None indent
    The indentation level of this Token (in number of leading spaces).
    bool inline
    If True, the element is an inline level element, comparable to an HTML <span> tag.
    int or None level
    The heading-level of this Token if it is a heading; None, otherwise.
    int startline
    The line on which this Token begins.
    string tag
    This Token's type.
    Method Details [hide private]

    __init__(self, tag, startline, contents, indent, level=None, inline=False)
    (Constructor)

    source code 
    call graph 

    Create a new Token.

    Parameters:
    • tag (string) - The type of the new Token.
    • startline (int) - The line on which the new Token begins.
    • contents (string) - The normalized contents of the new Token.
    • indent (int or None) - The indentation of the new Token (in number of leading spaces). A value of None indicates an unknown indentation.
    • level (int or None) - The heading-level of this Token if it is a heading; None, otherwise.
    • inline (bool) - Is this Token inline as a <span>?.

    __repr__(self)
    (Representation operator)

    source code 
    Returns: string
    the formal representation of this Token. Tokens have formal representaitons of the form:
       <Token: para at line 12>
    

    to_dom(self, doc)

    source code 
    call graph 
    Returns: Element
    a DOM representation of this Token.

    Class Variable Details [hide private]

    BULLET

    The tag value for bullet Tokens. This tag value is also used for field tag Tokens, since fields function syntactically the same as list items.
    Type:
    string
    Value:
    'bullet'
    

    Instance Variable Details [hide private]

    indent

    The indentation level of this Token (in number of leading spaces). A value of None indicates an unknown indentation; this is used for list items and fields that begin with one-line paragraphs.
    Type:
    int or None

    inline

    If True, the element is an inline level element, comparable to an HTML <span> tag. Else, it is a block level element, comparable to an HTML <div>.
    Type:
    bool

    level

    The heading-level of this Token if it is a heading; None, otherwise. Valid heading levels are 0, 1, and 2.
    Type:
    int or None

    startline

    The line on which this Token begins. This line number is only used for issuing errors.
    Type:
    int

    tag

    This Token's type. Possible values are Token.PARA (paragraph), Token.LBLOCK (literal block), Token.DTBLOCK (doctest block), Token.HEADINGC, and Token.BULLETC.
    Type:
    string

    epydoc-3.0.1+dfsg/doc/api/epydoc.docwriter.latex.LatexWriter._LatexDocstringLinker-class.html0000644000175000017500000002757410750103050032620 0ustar pronovicpronovic epydoc.docwriter.latex.LatexWriter._LatexDocstringLinker
    Package epydoc :: Package docwriter :: Module latex :: Class LatexWriter :: Class _LatexDocstringLinker
    [hide private]
    [frames] | no frames]

    Class _LatexDocstringLinker

    source code


    Instance Methods [hide private]
    string
    translate_indexterm(self, indexterm)
    Translate an index term to the appropriate output format.
    source code
    string
    translate_identifier_xref(self, identifier, label=None)
    Translate a crossreference link to a Python identifier to the appropriate output format.
    source code
    Method Details [hide private]

    translate_indexterm(self, indexterm)

    source code 

    Translate an index term to the appropriate output format. The output will typically include a crossreference anchor.

    Parameters:
    • indexterm - The index term to translate.
    Returns: string
    The translated index term.
    Overrides: markup.DocstringLinker.translate_indexterm
    (inherited documentation)

    translate_identifier_xref(self, identifier, label=None)

    source code 

    Translate a crossreference link to a Python identifier to the appropriate output format. The output will typically include a reference or pointer to the crossreference target.

    Parameters:
    • identifier - The name of the Python identifier that should be linked to.
    • label - The label that should be used for the identifier, if it's different from the name of the identifier.
    Returns: string
    The translated crossreference link.
    Overrides: markup.DocstringLinker.translate_identifier_xref
    (inherited documentation)

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.javadoc-module.html0000644000175000017500000002673710750103050024061 0ustar pronovicpronovic epydoc.markup.javadoc
    Package epydoc :: Package markup :: Module javadoc
    [hide private]
    [frames] | no frames]

    Module javadoc

    source code

    Epydoc parser for Javadoc docstrings. Javadoc is an HTML-based markup language that was developed for documenting Java APIs with inline comments. It consists of raw HTML, augmented by Javadoc tags. There are two types of Javadoc tag:

    • Javadoc block tags correspond to Epydoc fields. They are marked by starting a line with a string of the form "@tag [arg]", where tag indicates the type of block, and arg is an optional argument. (For fields that take arguments, Javadoc assumes that the single word immediately following the tag is an argument; multi-word arguments cannot be used with javadoc.)
    • inline Javadoc tags are used for inline markup. In particular, epydoc uses them for crossreference links between documentation. Inline tags may appear anywhere in the text, and have the form "{@tag [args...]}", where tag indicates the type of inline markup, and args are optional arguments.

    Epydoc supports all Javadoc tags, except:

    • {@docRoot}, which gives the (relative) URL of the generated documentation's root.
    • {@inheritDoc}, which copies the documentation of the nearest overridden object. This can be used to combine the documentation of the overridden object with the documentation of the overridding object.
    • @serial, @serialField, and @serialData which describe the serialization (pickling) of an object.
    • {@value}, which copies the value of a constant.

    Warning: Epydoc only supports HTML output for Javadoc docstrings.

    Classes [hide private]
      ParsedJavadocDocstring
    An encoded version of a Javadoc docstring.
    Functions [hide private]
    ParsedDocstring
    parse_docstring(docstring, errors, **options)
    Parse the given docstring, which is formatted using Javadoc; and return a ParsedDocstring representation of its contents.
    source code
    Function Details [hide private]

    parse_docstring(docstring, errors, **options)

    source code 

    Parse the given docstring, which is formatted using Javadoc; and return a ParsedDocstring representation of its contents.

    Parameters:
    • docstring (string) - The docstring to parse
    • errors (list of ParseError) - A list where any errors generated during parsing will be stored.
    • options - Extra options. Unknown options are ignored. Currently, no extra options are defined.
    Returns: ParsedDocstring

    epydoc-3.0.1+dfsg/doc/api/epydoc.markup.epytext-pysrc.html0000644000175000017500000240610010750103050024013 0ustar pronovicpronovic epydoc.markup.epytext
    Package epydoc :: Package markup :: Module epytext
    [hide private]
    [frames] | no frames]

    Source Code for Module epydoc.markup.epytext

       1  # 
       2  # epytext.py: epydoc formatted docstring parsing 
       3  # Edward Loper 
       4  # 
       5  # Created [04/10/01 12:00 AM] 
       6  # $Id: epytext.py 1652 2007-09-26 04:45:34Z edloper $ 
       7  # 
       8   
       9  """ 
      10  Parser for epytext strings.  Epytext is a lightweight markup whose 
      11  primary intended application is Python documentation strings.  This 
      12  parser converts Epytext strings to a simple DOM-like representation 
      13  (encoded as a tree of L{Element} objects and strings).  Epytext 
      14  strings can contain the following X{structural blocks}: 
      15   
      16      - X{epytext}: The top-level element of the DOM tree. 
      17      - X{para}: A paragraph of text.  Paragraphs contain no newlines,  
      18        and all spaces are soft. 
      19      - X{section}: A section or subsection. 
      20      - X{field}: A tagged field.  These fields provide information 
      21        about specific aspects of a Python object, such as the 
      22        description of a function's parameter, or the author of a 
      23        module. 
      24      - X{literalblock}: A block of literal text.  This text should be 
      25        displayed as it would be displayed in plaintext.  The 
      26        parser removes the appropriate amount of leading whitespace  
      27        from each line in the literal block. 
      28      - X{doctestblock}: A block containing sample python code, 
      29        formatted according to the specifications of the C{doctest} 
      30        module. 
      31      - X{ulist}: An unordered list. 
      32      - X{olist}: An ordered list. 
      33      - X{li}: A list item.  This tag is used both for unordered list 
      34        items and for ordered list items. 
      35   
      36  Additionally, the following X{inline regions} may be used within 
      37  C{para} blocks: 
      38       
      39      - X{code}:   Source code and identifiers. 
      40      - X{math}:   Mathematical expressions. 
      41      - X{index}:  A term which should be included in an index, if one 
      42                   is generated. 
      43      - X{italic}: Italicized text. 
      44      - X{bold}:   Bold-faced text. 
      45      - X{uri}:    A Universal Resource Indicator (URI) or Universal 
      46                   Resource Locator (URL) 
      47      - X{link}:   A Python identifier which should be hyperlinked to 
      48                   the named object's documentation, when possible. 
      49   
      50  The returned DOM tree will conform to the the following Document Type 
      51  Description:: 
      52   
      53     <!ENTITY % colorized '(code | math | index | italic | 
      54                            bold | uri | link | symbol)*'> 
      55   
      56     <!ELEMENT epytext ((para | literalblock | doctestblock | 
      57                        section | ulist | olist)*, fieldlist?)> 
      58   
      59     <!ELEMENT para (#PCDATA | %colorized;)*> 
      60   
      61     <!ELEMENT section (para | listblock | doctestblock | 
      62                        section | ulist | olist)+> 
      63   
      64     <!ELEMENT fieldlist (field+)> 
      65     <!ELEMENT field (tag, arg?, (para | listblock | doctestblock) 
      66                                  ulist | olist)+)> 
      67     <!ELEMENT tag (#PCDATA)> 
      68     <!ELEMENT arg (#PCDATA)> 
      69      
      70     <!ELEMENT literalblock (#PCDATA | %colorized;)*> 
      71     <!ELEMENT doctestblock (#PCDATA)> 
      72   
      73     <!ELEMENT ulist (li+)> 
      74     <!ELEMENT olist (li+)> 
      75     <!ELEMENT li (para | literalblock | doctestblock | ulist | olist)+> 
      76     <!ATTLIST li bullet NMTOKEN #IMPLIED> 
      77     <!ATTLIST olist start NMTOKEN #IMPLIED> 
      78   
      79     <!ELEMENT uri     (name, target)> 
      80     <!ELEMENT link    (name, target)> 
      81     <!ELEMENT name    (#PCDATA | %colorized;)*> 
      82     <!ELEMENT target  (#PCDATA)> 
      83      
      84     <!ELEMENT code    (#PCDATA | %colorized;)*> 
      85     <!ELEMENT math    (#PCDATA | %colorized;)*> 
      86     <!ELEMENT italic  (#PCDATA | %colorized;)*> 
      87     <!ELEMENT bold    (#PCDATA | %colorized;)*> 
      88     <!ELEMENT indexed (#PCDATA | %colorized;)> 
      89     <!ATTLIST code style CDATA #IMPLIED> 
      90   
      91     <!ELEMENT symbol (#PCDATA)> 
      92   
      93  @var SYMBOLS: A list of the of escape symbols that are supported 
      94        by epydoc.  Currently the following symbols are supported: 
      95  <<<SYMBOLS>>> 
      96  """ 
      97  # Note: the symbol list is appended to the docstring automatically, 
      98  # below. 
      99   
     100  __docformat__ = 'epytext en' 
     101   
     102  # Code organization.. 
     103  #   1. parse() 
     104  #   2. tokenize() 
     105  #   3. colorize() 
     106  #   4. helpers 
     107  #   5. testing 
     108   
     109  import re, string, types, sys, os.path 
     110  from epydoc.markup import * 
     111  from epydoc.util import wordwrap, plaintext_to_html, plaintext_to_latex 
     112  from epydoc.markup.doctest import doctest_to_html, doctest_to_latex 
     113   
     114  ################################################## 
     115  ## DOM-Like Encoding 
     116  ################################################## 
     117   
    
    118 -class Element:
    119 """ 120 A very simple DOM-like representation for parsed epytext 121 documents. Each epytext document is encoded as a tree whose nodes 122 are L{Element} objects, and whose leaves are C{string}s. Each 123 node is marked by a I{tag} and zero or more I{attributes}. Each 124 attribute is a mapping from a string key to a string value. 125 """
    126 - def __init__(self, tag, *children, **attribs):
    127 self.tag = tag 128 """A string tag indicating the type of this element. 129 @type: C{string}""" 130 131 self.children = list(children) 132 """A list of the children of this element. 133 @type: C{list} of (C{string} or C{Element})""" 134 135 self.attribs = attribs 136 """A dictionary mapping attribute names to attribute values 137 for this element. 138 @type: C{dict} from C{string} to C{string}"""
    139
    140 - def __str__(self):
    141 """ 142 Return a string representation of this element, using XML 143 notation. 144 @bug: Doesn't escape '<' or '&' or '>'. 145 """ 146 attribs = ''.join([' %s=%r' % t for t in self.attribs.items()]) 147 return ('<%s%s>' % (self.tag, attribs) + 148 ''.join([str(child) for child in self.children]) + 149 '</%s>' % self.tag)
    150
    151 - def __repr__(self):
    152 attribs = ''.join([', %s=%r' % t for t in self.attribs.items()]) 153 args = ''.join([', %r' % c for c in self.children]) 154 return 'Element(%s%s%s)' % (self.tag, args, attribs)
    155 156 ################################################## 157 ## Constants 158 ################################################## 159 160 # The possible heading underline characters, listed in order of 161 # heading depth. 162 _HEADING_CHARS = "=-~" 163 164 # Escape codes. These should be needed very rarely. 165 _ESCAPES = {'lb':'{', 'rb': '}'} 166 167 # Symbols. These can be generated via S{...} escapes. 168 SYMBOLS = [ 169 # Arrows 170 '<-', '->', '^', 'v', 171 172 # Greek letters 173 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 174 'eta', 'theta', 'iota', 'kappa', 'lambda', 'mu', 175 'nu', 'xi', 'omicron', 'pi', 'rho', 'sigma', 176 'tau', 'upsilon', 'phi', 'chi', 'psi', 'omega', 177 'Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 178 'Eta', 'Theta', 'Iota', 'Kappa', 'Lambda', 'Mu', 179 'Nu', 'Xi', 'Omicron', 'Pi', 'Rho', 'Sigma', 180 'Tau', 'Upsilon', 'Phi', 'Chi', 'Psi', 'Omega', 181 182 # HTML character entities 183 'larr', 'rarr', 'uarr', 'darr', 'harr', 'crarr', 184 'lArr', 'rArr', 'uArr', 'dArr', 'hArr', 185 'copy', 'times', 'forall', 'exist', 'part', 186 'empty', 'isin', 'notin', 'ni', 'prod', 'sum', 187 'prop', 'infin', 'ang', 'and', 'or', 'cap', 'cup', 188 'int', 'there4', 'sim', 'cong', 'asymp', 'ne', 189 'equiv', 'le', 'ge', 'sub', 'sup', 'nsub', 190 'sube', 'supe', 'oplus', 'otimes', 'perp', 191 192 # Alternate (long) names 193 'infinity', 'integral', 'product', 194 '>=', '<=', 195 ] 196 # Convert to a dictionary, for quick lookup 197 _SYMBOLS = {} 198 for symbol in SYMBOLS: _SYMBOLS[symbol] = 1 199 200 # Add symbols to the docstring. 201 symblist = ' ' 202 symblist += ';\n '.join([' - C{E{S}{%s}}=S{%s}' % (symbol, symbol) 203 for symbol in SYMBOLS]) 204 __doc__ = __doc__.replace('<<<SYMBOLS>>>', symblist) 205 del symbol, symblist 206 207 # Tags for colorizing text. 208 _COLORIZING_TAGS = { 209 'C': 'code', 210 'M': 'math', 211 'X': 'indexed', 212 'I': 'italic', 213 'B': 'bold', 214 'U': 'uri', 215 'L': 'link', # A Python identifier that should be linked to 216 'E': 'escape', # escapes characters or creates symbols 217 'S': 'symbol', 218 'G': 'graph', 219 } 220 221 # Which tags can use "link syntax" (e.g., U{Python<www.python.org>})? 222 _LINK_COLORIZING_TAGS = ['link', 'uri'] 223 224 ################################################## 225 ## Structuring (Top Level) 226 ################################################## 227
    228 -def parse(str, errors = None):
    229 """ 230 Return a DOM tree encoding the contents of an epytext string. Any 231 errors generated during parsing will be stored in C{errors}. 232 233 @param str: The epytext string to parse. 234 @type str: C{string} 235 @param errors: A list where any errors generated during parsing 236 will be stored. If no list is specified, then fatal errors 237 will generate exceptions, and non-fatal errors will be 238 ignored. 239 @type errors: C{list} of L{ParseError} 240 @return: a DOM tree encoding the contents of an epytext string. 241 @rtype: C{Element} 242 @raise ParseError: If C{errors} is C{None} and an error is 243 encountered while parsing. 244 """ 245 # Initialize errors list. 246 if errors == None: 247 errors = [] 248 raise_on_error = 1 249 else: 250 raise_on_error = 0 251 252 # Preprocess the string. 253 str = re.sub('\015\012', '\012', str) 254 str = string.expandtabs(str) 255 256 # Tokenize the input string. 257 tokens = _tokenize(str, errors) 258 259 # Have we encountered a field yet? 260 encountered_field = 0 261 262 # Create an document to hold the epytext. 263 doc = Element('epytext') 264 265 # Maintain two parallel stacks: one contains DOM elements, and 266 # gives the ancestors of the current block. The other contains 267 # indentation values, and gives the indentation of the 268 # corresponding DOM elements. An indentation of "None" reflects 269 # an unknown indentation. However, the indentation must be 270 # greater than, or greater than or equal to, the indentation of 271 # the prior element (depending on what type of DOM element it 272 # corresponds to). No 2 consecutive indent_stack values will be 273 # ever be "None." Use initial dummy elements in the stack, so we 274 # don't have to worry about bounds checking. 275 stack = [None, doc] 276 indent_stack = [-1, None] 277 278 for token in tokens: 279 # Uncomment this for debugging: 280 #print ('%s: %s\n%s: %s\n' % 281 # (''.join(['%-11s' % (t and t.tag) for t in stack]), 282 # token.tag, ''.join(['%-11s' % i for i in indent_stack]), 283 # token.indent)) 284 285 # Pop any completed blocks off the stack. 286 _pop_completed_blocks(token, stack, indent_stack) 287 288 # If Token has type PARA, colorize and add the new paragraph 289 if token.tag == Token.PARA: 290 _add_para(doc, token, stack, indent_stack, errors) 291 292 # If Token has type HEADING, add the new section 293 elif token.tag == Token.HEADING: 294 _add_section(doc, token, stack, indent_stack, errors) 295 296 # If Token has type LBLOCK, add the new literal block 297 elif token.tag == Token.LBLOCK: 298 stack[-1].children.append(token.to_dom(doc)) 299 300 # If Token has type DTBLOCK, add the new doctest block 301 elif token.tag == Token.DTBLOCK: 302 stack[-1].children.append(token.to_dom(doc)) 303 304 # If Token has type BULLET, add the new list/list item/field 305 elif token.tag == Token.BULLET: 306 _add_list(doc, token, stack, indent_stack, errors) 307 else: 308 assert 0, 'Unknown token type: '+token.tag 309 310 # Check if the DOM element we just added was a field.. 311 if stack[-1].tag == 'field': 312 encountered_field = 1 313 elif encountered_field == 1: 314 if len(stack) <= 3: 315 estr = ("Fields must be the final elements in an "+ 316 "epytext string.") 317 errors.append(StructuringError(estr, token.startline)) 318 319 # Graphs use inline markup (G{...}) but are really block-level 320 # elements; so "raise" any graphs we generated. This is a bit of 321 # a hack, but the alternative is to define a new markup for 322 # block-level elements, which I'd rather not do. (See sourceforge 323 # bug #1673017.) 324 for child in doc.children: 325 _raise_graphs(child, doc) 326 327 # If there was an error, then signal it! 328 if len([e for e in errors if e.is_fatal()]) > 0: 329 if raise_on_error: 330 raise errors[0] 331 else: 332 return None 333 334 # Return the top-level epytext DOM element. 335 return doc
    336
    337 -def _raise_graphs(tree, parent):
    338 # Recurse to children. 339 have_graph_child = False 340 for elt in tree.children: 341 if isinstance(elt, Element): 342 _raise_graphs(elt, tree) 343 if elt.tag == 'graph': have_graph_child = True 344 345 block = ('section', 'fieldlist', 'field', 'ulist', 'olist', 'li') 346 if have_graph_child and tree.tag not in block: 347 child_index = 0 348 for elt in tree.children: 349 if isinstance(elt, Element) and elt.tag == 'graph': 350 # We found a graph: splice it into the parent. 351 parent_index = parent.children.index(tree) 352 left = tree.children[:child_index] 353 right = tree.children[child_index+1:] 354 parent.children[parent_index:parent_index+1] = [ 355 Element(tree.tag, *left, **tree.attribs), 356 elt, 357 Element(tree.tag, *right, **tree.attribs)] 358 child_index = 0 359 parent_index += 2 360 else: 361 child_index += 1
    362
    363 -def _pop_completed_blocks(token, stack, indent_stack):
    364 """ 365 Pop any completed blocks off the stack. This includes any 366 blocks that we have dedented past, as well as any list item 367 blocks that we've dedented to. The top element on the stack 368 should only be a list if we're about to start a new list 369 item (i.e., if the next token is a bullet). 370 """ 371 indent = token.indent 372 if indent != None: 373 while (len(stack) > 2): 374 pop = 0 375 376 # Dedent past a block 377 if indent_stack[-1]!=None and indent<indent_stack[-1]: pop=1 378 elif indent_stack[-1]==None and indent<indent_stack[-2]: pop=1 379 380 # Dedent to a list item, if it is follwed by another list 381 # item with the same indentation. 382 elif (token.tag == 'bullet' and indent==indent_stack[-2] and 383 stack[-1].tag in ('li', 'field')): pop=1 384 385 # End of a list (no more list items available) 386 elif (stack[-1].tag in ('ulist', 'olist') and 387 (token.tag != 'bullet' or token.contents[-1] == ':')): 388 pop=1 389 390 # Pop the block, if it's complete. Otherwise, we're done. 391 if pop == 0: return 392 stack.pop() 393 indent_stack.pop()
    394
    395 -def _add_para(doc, para_token, stack, indent_stack, errors):
    396 """Colorize the given paragraph, and add it to the DOM tree.""" 397 # Check indentation, and update the parent's indentation 398 # when appropriate. 399 if indent_stack[-1] == None: 400 indent_stack[-1] = para_token.indent 401 if para_token.indent == indent_stack[-1]: 402 # Colorize the paragraph and add it. 403 para = _colorize(doc, para_token, errors) 404 if para_token.inline: 405 para.attribs['inline'] = True 406 stack[-1].children.append(para) 407 else: 408 estr = "Improper paragraph indentation." 409 errors.append(StructuringError(estr, para_token.startline))
    410
    411 -def _add_section(doc, heading_token, stack, indent_stack, errors):
    412 """Add a new section to the DOM tree, with the given heading.""" 413 if indent_stack[-1] == None: 414 indent_stack[-1] = heading_token.indent 415 elif indent_stack[-1] != heading_token.indent: 416 estr = "Improper heading indentation." 417 errors.append(StructuringError(estr, heading_token.startline)) 418 419 # Check for errors. 420 for tok in stack[2:]: 421 if tok.tag != "section": 422 estr = "Headings must occur at the top level." 423 errors.append(StructuringError(estr, heading_token.startline)) 424 break 425 if (heading_token.level+2) > len(stack): 426 estr = "Wrong underline character for heading." 427 errors.append(StructuringError(estr, heading_token.startline)) 428 429 # Pop the appropriate number of headings so we're at the 430 # correct level. 431 stack[heading_token.level+2:] = [] 432 indent_stack[heading_token.level+2:] = [] 433 434 # Colorize the heading 435 head = _colorize(doc, heading_token, errors, 'heading') 436 437 # Add the section's and heading's DOM elements. 438 sec = Element("section") 439 stack[-1].children.append(sec) 440 stack.append(sec) 441 sec.children.append(head) 442 indent_stack.append(None)
    443
    444 -def _add_list(doc, bullet_token, stack, indent_stack, errors):
    445 """ 446 Add a new list item or field to the DOM tree, with the given 447 bullet or field tag. When necessary, create the associated 448 list. 449 """ 450 # Determine what type of bullet it is. 451 if bullet_token.contents[-1] == '-': 452 list_type = 'ulist' 453 elif bullet_token.contents[-1] == '.': 454 list_type = 'olist' 455 elif bullet_token.contents[-1] == ':': 456 list_type = 'fieldlist' 457 else: 458 raise AssertionError('Bad Bullet: %r' % bullet_token.contents) 459 460 # Is this a new list? 461 newlist = 0 462 if stack[-1].tag != list_type: 463 newlist = 1 464 elif list_type == 'olist' and stack[-1].tag == 'olist': 465 old_listitem = stack[-1].children[-1] 466 old_bullet = old_listitem.attribs.get("bullet").split('.')[:-1] 467 new_bullet = bullet_token.contents.split('.')[:-1] 468 if (new_bullet[:-1] != old_bullet[:-1] or 469 int(new_bullet[-1]) != int(old_bullet[-1])+1): 470 newlist = 1 471 472 # Create the new list. 473 if newlist: 474 if stack[-1].tag is 'fieldlist': 475 # The new list item is not a field list item (since this 476 # is a new list); but it's indented the same as the field 477 # list. This either means that they forgot to indent the 478 # list, or they are trying to put something after the 479 # field list. The first one seems more likely, so we'll 480 # just warn about that (to avoid confusion). 481 estr = "Lists must be indented." 482 errors.append(StructuringError(estr, bullet_token.startline)) 483 if stack[-1].tag in ('ulist', 'olist', 'fieldlist'): 484 stack.pop() 485 indent_stack.pop() 486 487 if (list_type != 'fieldlist' and indent_stack[-1] is not None and 488 bullet_token.indent == indent_stack[-1]): 489 # Ignore this error if there's text on the same line as 490 # the comment-opening quote -- epydoc can't reliably 491 # determine the indentation for that line. 492 if bullet_token.startline != 1 or bullet_token.indent != 0: 493 estr = "Lists must be indented." 494 errors.append(StructuringError(estr, bullet_token.startline)) 495 496 if list_type == 'fieldlist': 497 # Fieldlist should be at the top-level. 498 for tok in stack[2:]: 499 if tok.tag != "section": 500 estr = "Fields must be at the top level." 501 errors.append( 502 StructuringError(estr, bullet_token.startline)) 503 break 504 stack[2:] = [] 505 indent_stack[2:] = [] 506 507 # Add the new list. 508 lst = Element(list_type) 509 stack[-1].children.append(lst) 510 stack.append(lst) 511 indent_stack.append(bullet_token.indent) 512 if list_type == 'olist': 513 start = bullet_token.contents.split('.')[:-1] 514 if start != '1': 515 lst.attribs["start"] = start[-1] 516 517 # Fields are treated somewhat specially: A "fieldlist" 518 # node is created to make the parsing simpler, but fields 519 # are adjoined directly into the "epytext" node, not into 520 # the "fieldlist" node. 521 if list_type == 'fieldlist': 522 li = Element("field") 523 token_words = bullet_token.contents[1:-1].split(None, 1) 524 tag_elt = Element("tag") 525 tag_elt.children.append(token_words[0]) 526 li.children.append(tag_elt) 527 528 if len(token_words) > 1: 529 arg_elt = Element("arg") 530 arg_elt.children.append(token_words[1]) 531 li.children.append(arg_elt) 532 else: 533 li = Element("li") 534 if list_type == 'olist': 535 li.attribs["bullet"] = bullet_token.contents 536 537 # Add the bullet. 538 stack[-1].children.append(li) 539 stack.append(li) 540 indent_stack.append(None)
    541 542 ################################################## 543 ## Tokenization 544 ################################################## 545
    546 -class Token:
    547 """ 548 C{Token}s are an intermediate data structure used while 549 constructing the structuring DOM tree for a formatted docstring. 550 There are five types of C{Token}: 551 552 - Paragraphs 553 - Literal blocks 554 - Doctest blocks 555 - Headings 556 - Bullets 557 558 The text contained in each C{Token} is stored in the 559 C{contents} variable. The string in this variable has been 560 normalized. For paragraphs, this means that it has been converted 561 into a single line of text, with newline/indentation replaced by 562 single spaces. For literal blocks and doctest blocks, this means 563 that the appropriate amount of leading whitespace has been removed 564 from each line. 565 566 Each C{Token} has an indentation level associated with it, 567 stored in the C{indent} variable. This indentation level is used 568 by the structuring procedure to assemble hierarchical blocks. 569 570 @type tag: C{string} 571 @ivar tag: This C{Token}'s type. Possible values are C{Token.PARA} 572 (paragraph), C{Token.LBLOCK} (literal block), C{Token.DTBLOCK} 573 (doctest block), C{Token.HEADINGC}, and C{Token.BULLETC}. 574 575 @type startline: C{int} 576 @ivar startline: The line on which this C{Token} begins. This 577 line number is only used for issuing errors. 578 579 @type contents: C{string} 580 @ivar contents: The normalized text contained in this C{Token}. 581 582 @type indent: C{int} or C{None} 583 @ivar indent: The indentation level of this C{Token} (in 584 number of leading spaces). A value of C{None} indicates an 585 unknown indentation; this is used for list items and fields 586 that begin with one-line paragraphs. 587 588 @type level: C{int} or C{None} 589 @ivar level: The heading-level of this C{Token} if it is a 590 heading; C{None}, otherwise. Valid heading levels are 0, 1, 591 and 2. 592 593 @type inline: C{bool} 594 @ivar inline: If True, the element is an inline level element, comparable 595 to an HTML C{<span>} tag. Else, it is a block level element, comparable 596 to an HTML C{<div>}. 597 598 @type PARA: C{string} 599 @cvar PARA: The C{tag} value for paragraph C{Token}s. 600 @type LBLOCK: C{string} 601 @cvar LBLOCK: The C{tag} value for literal C{Token}s. 602 @type DTBLOCK: C{string} 603 @cvar DTBLOCK: The C{tag} value for doctest C{Token}s. 604 @type HEADING: C{string} 605 @cvar HEADING: The C{tag} value for heading C{Token}s. 606 @type BULLET: C{string} 607 @cvar BULLET: The C{tag} value for bullet C{Token}s. This C{tag} 608 value is also used for field tag C{Token}s, since fields 609 function syntactically the same as list items. 610 """ 611 # The possible token types. 612 PARA = "para" 613 LBLOCK = "literalblock" 614 DTBLOCK = "doctestblock" 615 HEADING = "heading" 616 BULLET = "bullet" 617
    618 - def __init__(self, tag, startline, contents, indent, level=None, 619 inline=False):
    620 """ 621 Create a new C{Token}. 622 623 @param tag: The type of the new C{Token}. 624 @type tag: C{string} 625 @param startline: The line on which the new C{Token} begins. 626 @type startline: C{int} 627 @param contents: The normalized contents of the new C{Token}. 628 @type contents: C{string} 629 @param indent: The indentation of the new C{Token} (in number 630 of leading spaces). A value of C{None} indicates an 631 unknown indentation. 632 @type indent: C{int} or C{None} 633 @param level: The heading-level of this C{Token} if it is a 634 heading; C{None}, otherwise. 635 @type level: C{int} or C{None} 636 @param inline: Is this C{Token} inline as a C{<span>}?. 637 @type inline: C{bool} 638 """ 639 self.tag = tag 640 self.startline = startline 641 self.contents = contents 642 self.indent = indent 643 self.level = level 644 self.inline = inline
    645
    646 - def __repr__(self):
    647 """ 648 @rtype: C{string} 649 @return: the formal representation of this C{Token}. 650 C{Token}s have formal representaitons of the form:: 651 <Token: para at line 12> 652 """ 653 return '<Token: %s at line %s>' % (self.tag, self.startline)
    654
    655 - def to_dom(self, doc):
    656 """ 657 @return: a DOM representation of this C{Token}. 658 @rtype: L{Element} 659 """ 660 e = Element(self.tag) 661 e.children.append(self.contents) 662 return e
    663 664 # Construct regular expressions for recognizing bullets. These are 665 # global so they don't have to be reconstructed each time we tokenize 666 # a docstring. 667 _ULIST_BULLET = '[-]( +|$)' 668 _OLIST_BULLET = '(\d+[.])+( +|$)' 669 _FIELD_BULLET = '@\w+( [^{}:\n]+)?:' 670 _BULLET_RE = re.compile(_ULIST_BULLET + '|' + 671 _OLIST_BULLET + '|' + 672 _FIELD_BULLET) 673 _LIST_BULLET_RE = re.compile(_ULIST_BULLET + '|' + _OLIST_BULLET) 674 _FIELD_BULLET_RE = re.compile(_FIELD_BULLET) 675 del _ULIST_BULLET, _OLIST_BULLET, _FIELD_BULLET 676
    677 -def _tokenize_doctest(lines, start, block_indent, tokens, errors):
    678 """ 679 Construct a L{Token} containing the doctest block starting at 680 C{lines[start]}, and append it to C{tokens}. C{block_indent} 681 should be the indentation of the doctest block. Any errors 682 generated while tokenizing the doctest block will be appended to 683 C{errors}. 684 685 @param lines: The list of lines to be tokenized 686 @param start: The index into C{lines} of the first line of the 687 doctest block to be tokenized. 688 @param block_indent: The indentation of C{lines[start]}. This is 689 the indentation of the doctest block. 690 @param errors: A list where any errors generated during parsing 691 will be stored. If no list is specified, then errors will 692 generate exceptions. 693 @return: The line number of the first line following the doctest 694 block. 695 696 @type lines: C{list} of C{string} 697 @type start: C{int} 698 @type block_indent: C{int} 699 @type tokens: C{list} of L{Token} 700 @type errors: C{list} of L{ParseError} 701 @rtype: C{int} 702 """ 703 # If they dedent past block_indent, keep track of the minimum 704 # indentation. This is used when removing leading indentation 705 # from the lines of the doctest block. 706 min_indent = block_indent 707 708 linenum = start + 1 709 while linenum < len(lines): 710 # Find the indentation of this line. 711 line = lines[linenum] 712 indent = len(line) - len(line.lstrip()) 713 714 # A blank line ends doctest block. 715 if indent == len(line): break 716 717 # A Dedent past block_indent is an error. 718 if indent < block_indent: 719 min_indent = min(min_indent, indent) 720 estr = 'Improper doctest block indentation.' 721 errors.append(TokenizationError(estr, linenum)) 722 723 # Go on to the next line. 724 linenum += 1 725 726 # Add the token, and return the linenum after the token ends. 727 contents = [line[min_indent:] for line in lines[start:linenum]] 728 contents = '\n'.join(contents) 729 tokens.append(Token(Token.DTBLOCK, start, contents, block_indent)) 730 return linenum
    731
    732 -def _tokenize_literal(lines, start, block_indent, tokens, errors):
    733 """ 734 Construct a L{Token} containing the literal block starting at 735 C{lines[start]}, and append it to C{tokens}. C{block_indent} 736 should be the indentation of the literal block. Any errors 737 generated while tokenizing the literal block will be appended to 738 C{errors}. 739 740 @param lines: The list of lines to be tokenized 741 @param start: The index into C{lines} of the first line of the 742 literal block to be tokenized. 743 @param block_indent: The indentation of C{lines[start]}. This is 744 the indentation of the literal block. 745 @param errors: A list of the errors generated by parsing. Any 746 new errors generated while will tokenizing this paragraph 747 will be appended to this list. 748 @return: The line number of the first line following the literal 749 block. 750 751 @type lines: C{list} of C{string} 752 @type start: C{int} 753 @type block_indent: C{int} 754 @type tokens: C{list} of L{Token} 755 @type errors: C{list} of L{ParseError} 756 @rtype: C{int} 757 """ 758 linenum = start + 1 759 while linenum < len(lines): 760 # Find the indentation of this line. 761 line = lines[linenum] 762 indent = len(line) - len(line.lstrip()) 763 764 # A Dedent to block_indent ends the literal block. 765 # (Ignore blank likes, though) 766 if len(line) != indent and indent <= block_indent: 767 break 768 769 # Go on to the next line. 770 linenum += 1 771 772 # Add the token, and return the linenum after the token ends. 773 contents = [line[block_indent+1:] for line in lines[start:linenum]] 774 contents = '\n'.join(contents) 775 contents = re.sub('(\A[ \n]*\n)|(\n[ \n]*\Z)', '', contents) 776 tokens.append(Token(Token.LBLOCK, start, contents, block_indent)) 777 return linenum
    778
    779 -def _tokenize_listart(lines, start, bullet_indent, tokens, errors):
    780 """ 781 Construct L{Token}s for the bullet and the first paragraph of the 782 list item (or field) starting at C{lines[start]}, and append them 783 to C{tokens}. C{bullet_indent} should be the indentation of the 784 list item. Any errors generated while tokenizing will be 785 appended to C{errors}. 786 787 @param lines: The list of lines to be tokenized 788 @param start: The index into C{lines} of the first line of the 789 list item to be tokenized. 790 @param bullet_indent: The indentation of C{lines[start]}. This is 791 the indentation of the list item. 792 @param errors: A list of the errors generated by parsing. Any 793 new errors generated while will tokenizing this paragraph 794 will be appended to this list. 795 @return: The line number of the first line following the list 796 item's first paragraph. 797 798 @type lines: C{list} of C{string} 799 @type start: C{int} 800 @type bullet_indent: C{int} 801 @type tokens: C{list} of L{Token} 802 @type errors: C{list} of L{ParseError} 803 @rtype: C{int} 804 """ 805 linenum = start + 1 806 para_indent = None 807 doublecolon = lines[start].rstrip()[-2:] == '::' 808 809 # Get the contents of the bullet. 810 para_start = _BULLET_RE.match(lines[start], bullet_indent).end() 811 bcontents = lines[start][bullet_indent:para_start].strip() 812 813 while linenum < len(lines): 814 # Find the indentation of this line. 815 line = lines[linenum] 816 indent = len(line) - len(line.lstrip()) 817 818 # "::" markers end paragraphs. 819 if doublecolon: break 820 if line.rstrip()[-2:] == '::': doublecolon = 1 821 822 # A blank line ends the token 823 if indent == len(line): break 824 825 # Dedenting past bullet_indent ends the list item. 826 if indent < bullet_indent: break 827 828 # A line beginning with a bullet ends the token. 829 if _BULLET_RE.match(line, indent): break 830 831 # If this is the second line, set the paragraph indentation, or 832 # end the token, as appropriate. 833 if para_indent == None: para_indent = indent 834 835 # A change in indentation ends the token 836 if indent != para_indent: break 837 838 # Go on to the next line. 839 linenum += 1 840 841 # Add the bullet token. 842 tokens.append(Token(Token.BULLET, start, bcontents, bullet_indent, 843 inline=True)) 844 845 # Add the paragraph token. 846 pcontents = ([lines[start][para_start:].strip()] + 847 [line.strip() for line in lines[start+1:linenum]]) 848 pcontents = ' '.join(pcontents).strip() 849 if pcontents: 850 tokens.append(Token(Token.PARA, start, pcontents, para_indent, 851 inline=True)) 852 853 # Return the linenum after the paragraph token ends. 854 return linenum
    855
    856 -def _tokenize_para(lines, start, para_indent, tokens, errors):
    857 """ 858 Construct a L{Token} containing the paragraph starting at 859 C{lines[start]}, and append it to C{tokens}. C{para_indent} 860 should be the indentation of the paragraph . Any errors 861 generated while tokenizing the paragraph will be appended to 862 C{errors}. 863 864 @param lines: The list of lines to be tokenized 865 @param start: The index into C{lines} of the first line of the 866 paragraph to be tokenized. 867 @param para_indent: The indentation of C{lines[start]}. This is 868 the indentation of the paragraph. 869 @param errors: A list of the errors generated by parsing. Any 870 new errors generated while will tokenizing this paragraph 871 will be appended to this list. 872 @return: The line number of the first line following the 873 paragraph. 874 875 @type lines: C{list} of C{string} 876 @type start: C{int} 877 @type para_indent: C{int} 878 @type tokens: C{list} of L{Token} 879 @type errors: C{list} of L{ParseError} 880 @rtype: C{int} 881 """ 882 linenum = start + 1 883 doublecolon = 0 884 while linenum < len(lines): 885 # Find the indentation of this line. 886 line = lines[linenum] 887 indent = len(line) - len(line.lstrip()) 888 889 # "::" markers end paragraphs. 890 if doublecolon: break 891 if line.rstrip()[-2:] == '::': doublecolon = 1 892 893 # Blank lines end paragraphs 894 if indent == len(line): break 895 896 # Indentation changes end paragraphs 897 if indent != para_indent: break 898 899 # List bullets end paragraphs 900 if _BULLET_RE.match(line, indent): break 901 902 # Check for mal-formatted field items. 903 if line[indent] == '@': 904 estr = "Possible mal-formatted field item." 905 errors.append(TokenizationError(estr, linenum, is_fatal=0)) 906 907 # Go on to the next line. 908 linenum += 1 909 910 contents = [line.strip() for line in lines[start:linenum]] 911 912 # Does this token look like a heading? 913 if ((len(contents) < 2) or 914 (contents[1][0] not in _HEADING_CHARS) or 915 (abs(len(contents[0])-len(contents[1])) > 5)): 916 looks_like_heading = 0 917 else: 918 looks_like_heading = 1 919 for char in contents[1]: 920 if char != contents[1][0]: 921 looks_like_heading = 0 922 break 923 924 if looks_like_heading: 925 if len(contents[0]) != len(contents[1]): 926 estr = ("Possible heading typo: the number of "+ 927 "underline characters must match the "+ 928 "number of heading characters.") 929 errors.append(TokenizationError(estr, start, is_fatal=0)) 930 else: 931 level = _HEADING_CHARS.index(contents[1][0]) 932 tokens.append(Token(Token.HEADING, start, 933 contents[0], para_indent, level)) 934 return start+2 935 936 # Add the paragraph token, and return the linenum after it ends. 937 contents = ' '.join(contents) 938 tokens.append(Token(Token.PARA, start, contents, para_indent)) 939 return linenum
    940
    941 -def _tokenize(str, errors):
    942 """ 943 Split a given formatted docstring into an ordered list of 944 C{Token}s, according to the epytext markup rules. 945 946 @param str: The epytext string 947 @type str: C{string} 948 @param errors: A list where any errors generated during parsing 949 will be stored. If no list is specified, then errors will 950 generate exceptions. 951 @type errors: C{list} of L{ParseError} 952 @return: a list of the C{Token}s that make up the given string. 953 @rtype: C{list} of L{Token} 954 """ 955 tokens = [] 956 lines = str.split('\n') 957 958 # Scan through the lines, determining what @type of token we're 959 # dealing with, and tokenizing it, as appropriate. 960 linenum = 0 961 while linenum < len(lines): 962 # Get the current line and its indentation. 963 line = lines[linenum] 964 indent = len(line)-len(line.lstrip()) 965 966 if indent == len(line): 967 # Ignore blank lines. 968 linenum += 1 969 continue 970 elif line[indent:indent+4] == '>>> ': 971 # blocks starting with ">>> " are doctest block tokens. 972 linenum = _tokenize_doctest(lines, linenum, indent, 973 tokens, errors) 974 elif _BULLET_RE.match(line, indent): 975 # blocks starting with a bullet are LI start tokens. 976 linenum = _tokenize_listart(lines, linenum, indent, 977 tokens, errors) 978 if tokens[-1].indent != None: 979 indent = tokens[-1].indent 980 else: 981 # Check for mal-formatted field items. 982 if line[indent] == '@': 983 estr = "Possible mal-formatted field item." 984 errors.append(TokenizationError(estr, linenum, is_fatal=0)) 985 986 # anything else is either a paragraph or a heading. 987 linenum = _tokenize_para(lines, linenum, indent, tokens, errors) 988 989 # Paragraph tokens ending in '::' initiate literal blocks. 990 if (tokens[-1].tag == Token.PARA and 991 tokens[-1].contents[-2:] == '::'): 992 tokens[-1].contents = tokens[-1].contents[:-1] 993 linenum = _tokenize_literal(lines, linenum, indent, tokens, errors) 994 995 return tokens
    996 997 998 ################################################## 999 ## Inline markup ("colorizing") 1000 ################################################## 1001 1002 # Assorted regular expressions used for colorizing. 1003 _BRACE_RE = re.compile('{|}') 1004 _TARGET_RE = re.compile('^(.*?)\s*<(?:URI:|URL:)?([^<>]+)>$') 1005
    1006 -def _colorize(doc, token, errors, tagName='para'):
    1007 """ 1008 Given a string containing the contents of a paragraph, produce a 1009 DOM C{Element} encoding that paragraph. Colorized regions are 1010 represented using DOM C{Element}s, and text is represented using 1011 DOM C{Text}s. 1012 1013 @param errors: A list of errors. Any newly generated errors will 1014 be appended to this list. 1015 @type errors: C{list} of C{string} 1016 1017 @param tagName: The element tag for the DOM C{Element} that should 1018 be generated. 1019 @type tagName: C{string} 1020 1021 @return: a DOM C{Element} encoding the given paragraph. 1022 @returntype: C{Element} 1023 """ 1024 str = token.contents 1025 linenum = 0 1026 1027 # Maintain a stack of DOM elements, containing the ancestors of 1028 # the text currently being analyzed. New elements are pushed when 1029 # "{" is encountered, and old elements are popped when "}" is 1030 # encountered. 1031 stack = [Element(tagName)] 1032 1033 # This is just used to make error-reporting friendlier. It's a 1034 # stack parallel to "stack" containing the index of each element's 1035 # open brace. 1036 openbrace_stack = [0] 1037 1038 # Process the string, scanning for '{' and '}'s. start is the 1039 # index of the first unprocessed character. Each time through the 1040 # loop, we process the text from the first unprocessed character 1041 # to the next open or close brace. 1042 start = 0 1043 while 1: 1044 match = _BRACE_RE.search(str, start) 1045 if match == None: break 1046 end = match.start() 1047 1048 # Open braces start new colorizing elements. When preceeded 1049 # by a capital letter, they specify a colored region, as 1050 # defined by the _COLORIZING_TAGS dictionary. Otherwise, 1051 # use a special "literal braces" element (with tag "litbrace"), 1052 # and convert them to literal braces once we find the matching 1053 # close-brace. 1054 if match.group() == '{': 1055 if (end>0) and 'A' <= str[end-1] <= 'Z': 1056 if (end-1) > start: 1057 stack[-1].children.append(str[start:end-1]) 1058 if str[end-1] not in _COLORIZING_TAGS: 1059 estr = "Unknown inline markup tag." 1060 errors.append(ColorizingError(estr, token, end-1)) 1061 stack.append(Element('unknown')) 1062 else: 1063 tag = _COLORIZING_TAGS[str[end-1]] 1064 stack.append(Element(tag)) 1065 else: 1066 if end > start: 1067 stack[-1].children.append(str[start:end]) 1068 stack.append(Element('litbrace')) 1069 openbrace_stack.append(end) 1070 stack[-2].children.append(stack[-1]) 1071 1072 # Close braces end colorizing elements. 1073 elif match.group() == '}': 1074 # Check for (and ignore) unbalanced braces. 1075 if len(stack) <= 1: 1076 estr = "Unbalanced '}'." 1077 errors.append(ColorizingError(estr, token, end)) 1078 start = end + 1 1079 continue 1080 1081 # Add any remaining text. 1082 if end > start: 1083 stack[-1].children.append(str[start:end]) 1084 1085 # Special handling for symbols: 1086 if stack[-1].tag == 'symbol': 1087 if (len(stack[-1].children) != 1 or 1088 not isinstance(stack[-1].children[0], basestring)): 1089 estr = "Invalid symbol code." 1090 errors.append(ColorizingError(estr, token, end)) 1091 else: 1092 symb = stack[-1].children[0] 1093 if symb in _SYMBOLS: 1094 # It's a symbol 1095 stack[-2].children[-1] = Element('symbol', symb) 1096 else: 1097 estr = "Invalid symbol code." 1098 errors.append(ColorizingError(estr, token, end)) 1099 1100 # Special handling for escape elements: 1101 if stack[-1].tag == 'escape': 1102 if (len(stack[-1].children) != 1 or 1103 not isinstance(stack[-1].children[0], basestring)): 1104 estr = "Invalid escape code." 1105 errors.append(ColorizingError(estr, token, end)) 1106 else: 1107 escp = stack[-1].children[0] 1108 if escp in _ESCAPES: 1109 # It's an escape from _ESCPAES 1110 stack[-2].children[-1] = _ESCAPES[escp] 1111 elif len(escp) == 1: 1112 # It's a single-character escape (eg E{.}) 1113 stack[-2].children[-1] = escp 1114 else: 1115 estr = "Invalid escape code." 1116 errors.append(ColorizingError(estr, token, end)) 1117 1118 # Special handling for literal braces elements: 1119 if stack[-1].tag == 'litbrace': 1120 stack[-2].children[-1:] = ['{'] + stack[-1].children + ['}'] 1121 1122 # Special handling for graphs: 1123 if stack[-1].tag == 'graph': 1124 _colorize_graph(doc, stack[-1], token, end, errors) 1125 1126 # Special handling for link-type elements: 1127 if stack[-1].tag in _LINK_COLORIZING_TAGS: 1128 _colorize_link(doc, stack[-1], token, end, errors) 1129 1130 # Pop the completed element. 1131 openbrace_stack.pop() 1132 stack.pop() 1133 1134 start = end+1 1135 1136 # Add any final text. 1137 if start < len(str): 1138 stack[-1].children.append(str[start:]) 1139 1140 if len(stack) != 1: 1141 estr = "Unbalanced '{'." 1142 errors.append(ColorizingError(estr, token, openbrace_stack[-1])) 1143 1144 return stack[0]
    1145 1146 GRAPH_TYPES = ['classtree', 'packagetree', 'importgraph', 'callgraph'] 1147
    1148 -def _colorize_graph(doc, graph, token, end, errors):
    1149 """ 1150 Eg:: 1151 G{classtree} 1152 G{classtree x, y, z} 1153 G{importgraph} 1154 """ 1155 bad_graph_spec = False 1156 1157 children = graph.children[:] 1158 graph.children = [] 1159 1160 if len(children) != 1 or not isinstance(children[0], basestring): 1161 bad_graph_spec = "Bad graph specification" 1162 else: 1163 pieces = children[0].split(None, 1) 1164 graphtype = pieces[0].replace(':','').strip().lower() 1165 if graphtype in GRAPH_TYPES: 1166 if len(pieces) == 2: 1167 if re.match(r'\s*:?\s*([\w\.]+\s*,?\s*)*', pieces[1]): 1168 args = pieces[1].replace(',', ' ').replace(':','').split() 1169 else: 1170 bad_graph_spec = "Bad graph arg list" 1171 else: 1172 args = [] 1173 else: 1174 bad_graph_spec = ("Bad graph type %s -- use one of %s" % 1175 (pieces[0], ', '.join(GRAPH_TYPES))) 1176 1177 if bad_graph_spec: 1178 errors.append(ColorizingError(bad_graph_spec, token, end)) 1179 graph.children.append('none') 1180 graph.children.append('') 1181 return 1182 1183 graph.children.append(graphtype) 1184 for arg in args: 1185 graph.children.append(arg)
    1186 1234 1235 ################################################## 1236 ## Formatters 1237 ################################################## 1238
    1239 -def to_epytext(tree, indent=0, seclevel=0):
    1240 """ 1241 Convert a DOM document encoding epytext back to an epytext string. 1242 This is the inverse operation from L{parse}. I.e., assuming there 1243 are no errors, the following is true: 1244 - C{parse(to_epytext(tree)) == tree} 1245 1246 The inverse is true, except that whitespace, line wrapping, and 1247 character escaping may be done differently. 1248 - C{to_epytext(parse(str)) == str} (approximately) 1249 1250 @param tree: A DOM document encoding of an epytext string. 1251 @type tree: C{Element} 1252 @param indent: The indentation for the string representation of 1253 C{tree}. Each line of the returned string will begin with 1254 C{indent} space characters. 1255 @type indent: C{int} 1256 @param seclevel: The section level that C{tree} appears at. This 1257 is used to generate section headings. 1258 @type seclevel: C{int} 1259 @return: The epytext string corresponding to C{tree}. 1260 @rtype: C{string} 1261 """ 1262 if isinstance(tree, basestring): 1263 str = re.sub(r'\{', '\0', tree) 1264 str = re.sub(r'\}', '\1', str) 1265 return str 1266 1267 if tree.tag == 'epytext': indent -= 2 1268 if tree.tag == 'section': seclevel += 1 1269 variables = [to_epytext(c, indent+2, seclevel) for c in tree.children] 1270 childstr = ''.join(variables) 1271 1272 # Clean up for literal blocks (add the double "::" back) 1273 childstr = re.sub(':(\s*)\2', '::\\1', childstr) 1274 1275 if tree.tag == 'para': 1276 str = wordwrap(childstr, indent)+'\n' 1277 str = re.sub(r'((^|\n)\s*\d+)\.', r'\1E{.}', str) 1278 str = re.sub(r'((^|\n)\s*)-', r'\1E{-}', str) 1279 str = re.sub(r'((^|\n)\s*)@', r'\1E{@}', str) 1280 str = re.sub(r'::(\s*($|\n))', r'E{:}E{:}\1', str) 1281 str = re.sub('\0', 'E{lb}', str) 1282 str = re.sub('\1', 'E{rb}', str) 1283 return str 1284 elif tree.tag == 'li': 1285 bullet = tree.attribs.get('bullet') or '-' 1286 return indent*' '+ bullet + ' ' + childstr.lstrip() 1287 elif tree.tag == 'heading': 1288 str = re.sub('\0', 'E{lb}',childstr) 1289 str = re.sub('\1', 'E{rb}', str) 1290 uline = len(childstr)*_HEADING_CHARS[seclevel-1] 1291 return (indent-2)*' ' + str + '\n' + (indent-2)*' '+uline+'\n' 1292 elif tree.tag == 'doctestblock': 1293 str = re.sub('\0', '{', childstr) 1294 str = re.sub('\1', '}', str) 1295 lines = [' '+indent*' '+line for line in str.split('\n')] 1296 return '\n'.join(lines) + '\n\n' 1297 elif tree.tag == 'literalblock': 1298 str = re.sub('\0', '{', childstr) 1299 str = re.sub('\1', '}', str) 1300 lines = [(indent+1)*' '+line for line in str.split('\n')] 1301 return '\2' + '\n'.join(lines) + '\n\n' 1302 elif tree.tag == 'field': 1303 numargs = 0 1304 while tree.children[numargs+1].tag == 'arg': numargs += 1 1305 tag = variables[0] 1306 args = variables[1:1+numargs] 1307 body = variables[1+numargs:] 1308 str = (indent)*' '+'@'+variables[0] 1309 if args: str += '(' + ', '.join(args) + ')' 1310 return str + ':\n' + ''.join(body) 1311 elif tree.tag == 'target': 1312 return '<%s>' % childstr 1313 elif tree.tag in ('fieldlist', 'tag', 'arg', 'epytext', 1314 'section', 'olist', 'ulist', 'name'): 1315 return childstr 1316 elif tree.tag == 'symbol': 1317 return 'E{%s}' % childstr 1318 elif tree.tag == 'graph': 1319 return 'G{%s}' % ' '.join(variables) 1320 else: 1321 for (tag, name) in _COLORIZING_TAGS.items(): 1322 if name == tree.tag: 1323 return '%s{%s}' % (tag, childstr) 1324 raise ValueError('Unknown DOM element %r' % tree.tag)
    1325 1326 SYMBOL_TO_PLAINTEXT = { 1327 'crarr': '\\', 1328 } 1329
    1330 -def to_plaintext(tree, indent=0, seclevel=0):
    1331 """ 1332 Convert a DOM document encoding epytext to a string representation. 1333 This representation is similar to the string generated by 1334 C{to_epytext}, but C{to_plaintext} removes inline markup, prints 1335 escaped characters in unescaped form, etc. 1336 1337 @param tree: A DOM document encoding of an epytext string. 1338 @type tree: C{Element} 1339 @param indent: The indentation for the string representation of 1340 C{tree}. Each line of the returned string will begin with 1341 C{indent} space characters. 1342 @type indent: C{int} 1343 @param seclevel: The section level that C{tree} appears at. This 1344 is used to generate section headings. 1345 @type seclevel: C{int} 1346 @return: The epytext string corresponding to C{tree}. 1347 @rtype: C{string} 1348 """ 1349 if isinstance(tree, basestring): return tree 1350 1351 if tree.tag == 'section': seclevel += 1 1352 1353 # Figure out the child indent level. 1354 if tree.tag == 'epytext': cindent = indent 1355 elif tree.tag == 'li' and tree.attribs.get('bullet'): 1356 cindent = indent + 1 + len(tree.attribs.get('bullet')) 1357 else: 1358 cindent = indent + 2 1359 variables = [to_plaintext(c, cindent, seclevel) for c in tree.children] 1360 childstr = ''.join(variables) 1361 1362 if tree.tag == 'para': 1363 return wordwrap(childstr, indent)+'\n' 1364 elif tree.tag == 'li': 1365 # We should be able to use getAttribute here; but there's no 1366 # convenient way to test if an element has an attribute.. 1367 bullet = tree.attribs.get('bullet') or '-' 1368 return indent*' ' + bullet + ' ' + childstr.lstrip() 1369 elif tree.tag == 'heading': 1370 uline = len(childstr)*_HEADING_CHARS[seclevel-1] 1371 return ((indent-2)*' ' + childstr + '\n' + 1372 (indent-2)*' ' + uline + '\n') 1373 elif tree.tag == 'doctestblock': 1374 lines = [(indent+2)*' '+line for line in childstr.split('\n')] 1375 return '\n'.join(lines) + '\n\n' 1376 elif tree.tag == 'literalblock': 1377 lines = [(indent+1)*' '+line for line in childstr.split('\n')] 1378 return '\n'.join(lines) + '\n\n' 1379 elif tree.tag == 'fieldlist': 1380 return childstr 1381 elif tree.tag == 'field': 1382 numargs = 0 1383 while tree.children[numargs+1].tag == 'arg': numargs += 1 1384 tag = variables[0] 1385 args = variables[1:1+numargs] 1386 body = variables[1+numargs:] 1387 str = (indent)*' '+'@'+variables[0] 1388 if args: str += '(' + ', '.join(args) + ')' 1389 return str + ':\n' + ''.join(body) 1390 elif tree.tag == 'uri': 1391 if len(variables) != 2: raise ValueError('Bad URI ') 1392 elif variables[0] == variables[1]: return '<%s>' % variables[1] 1393 else: return '%r<%s>' % (variables[0], variables[1]) 1394 elif tree.tag == 'link': 1395 if len(variables) != 2: raise ValueError('Bad Link') 1396 return '%s' % variables[0] 1397 elif tree.tag in ('olist', 'ulist'): 1398 # [xx] always use condensed lists. 1399 ## Use a condensed list if each list item is 1 line long. 1400 #for child in variables: 1401 # if child.count('\n') > 2: return childstr 1402 return childstr.replace('\n\n', '\n')+'\n' 1403 elif tree.tag == 'symbol': 1404 return '%s' % SYMBOL_TO_PLAINTEXT.get(childstr, childstr) 1405 elif tree.tag == 'graph': 1406 return '<<%s graph: %s>>' % (variables[0], ', '.join(variables[1:])) 1407 else: 1408 # Assume that anything else can be passed through. 1409 return childstr
    1410
    1411 -def to_debug(tree, indent=4, seclevel=0):
    1412 """ 1413 Convert a DOM document encoding epytext back to an epytext string, 1414 annotated with extra debugging information. This function is 1415 similar to L{to_epytext}, but it adds explicit information about 1416 where different blocks begin, along the left margin. 1417 1418 @param tree: A DOM document encoding of an epytext string. 1419 @type tree: C{Element} 1420 @param indent: The indentation for the string representation of 1421 C{tree}. Each line of the returned string will begin with 1422 C{indent} space characters. 1423 @type indent: C{int} 1424 @param seclevel: The section level that C{tree} appears at. This 1425 is used to generate section headings. 1426 @type seclevel: C{int} 1427 @return: The epytext string corresponding to C{tree}. 1428 @rtype: C{string} 1429 """ 1430 if isinstance(tree, basestring): 1431 str = re.sub(r'\{', '\0', tree) 1432 str = re.sub(r'\}', '\1', str) 1433 return str 1434 1435 if tree.tag == 'section': seclevel += 1 1436 variables = [to_debug(c, indent+2, seclevel) for c in tree.children] 1437 childstr = ''.join(variables) 1438 1439 # Clean up for literal blocks (add the double "::" back) 1440 childstr = re.sub(':( *\n \|\n)\2', '::\\1', childstr) 1441 1442 if tree.tag == 'para': 1443 str = wordwrap(childstr, indent-6, 69)+'\n' 1444 str = re.sub(r'((^|\n)\s*\d+)\.', r'\1E{.}', str) 1445 str = re.sub(r'((^|\n)\s*)-', r'\1E{-}', str) 1446 str = re.sub(r'((^|\n)\s*)@', r'\1E{@}', str) 1447 str = re.sub(r'::(\s*($|\n))', r'E{:}E{:}\1', str) 1448 str = re.sub('\0', 'E{lb}', str) 1449 str = re.sub('\1', 'E{rb}', str) 1450 lines = str.rstrip().split('\n') 1451 lines[0] = ' P>|' + lines[0] 1452 lines[1:] = [' |'+l for l in lines[1:]] 1453 return '\n'.join(lines)+'\n |\n' 1454 elif tree.tag == 'li': 1455 bullet = tree.attribs.get('bullet') or '-' 1456 return ' LI>|'+ (indent-6)*' '+ bullet + ' ' + childstr[6:].lstrip() 1457 elif tree.tag in ('olist', 'ulist'): 1458 return 'LIST>|'+(indent-4)*' '+childstr[indent+2:] 1459 elif tree.tag == 'heading': 1460 str = re.sub('\0', 'E{lb}', childstr) 1461 str = re.sub('\1', 'E{rb}', str) 1462 uline = len(childstr)*_HEADING_CHARS[seclevel-1] 1463 return ('SEC'+`seclevel`+'>|'+(indent-8)*' ' + str + '\n' + 1464 ' |'+(indent-8)*' ' + uline + '\n') 1465 elif tree.tag == 'doctestblock': 1466 str = re.sub('\0', '{', childstr) 1467 str = re.sub('\1', '}', str) 1468 lines = [' |'+(indent-4)*' '+line for line in str.split('\n')] 1469 lines[0] = 'DTST>'+lines[0][5:] 1470 return '\n'.join(lines) + '\n |\n' 1471 elif tree.tag == 'literalblock': 1472 str = re.sub('\0', '{', childstr) 1473 str = re.sub('\1', '}', str) 1474 lines = [' |'+(indent-5)*' '+line for line in str.split('\n')] 1475 lines[0] = ' LIT>'+lines[0][5:] 1476 return '\2' + '\n'.join(lines) + '\n |\n' 1477 elif tree.tag == 'field': 1478 numargs = 0 1479 while tree.children[numargs+1].tag == 'arg': numargs += 1 1480 tag = variables[0] 1481 args = variables[1:1+numargs] 1482 body = variables[1+numargs:] 1483 str = ' FLD>|'+(indent-6)*' '+'@'+variables[0] 1484 if args: str += '(' + ', '.join(args) + ')' 1485 return str + ':\n' + ''.join(body) 1486 elif tree.tag == 'target': 1487 return '<%s>' % childstr 1488 elif tree.tag in ('fieldlist', 'tag', 'arg', 'epytext', 1489 'section', 'olist', 'ulist', 'name'): 1490 return childstr 1491 elif tree.tag == 'symbol': 1492 return 'E{%s}' % childstr 1493 elif tree.tag == 'graph': 1494 return 'G{%s}' % ' '.join(variables) 1495 else: 1496 for (tag, name) in _COLORIZING_TAGS.items(): 1497 if name == tree.tag: 1498 return '%s{%s}' % (tag, childstr) 1499 raise ValueError('Unknown DOM element %r' % tree.tag)
    1500 1501 ################################################## 1502 ## Top-Level Wrapper function 1503 ##################################################
    1504 -def pparse(str, show_warnings=1, show_errors=1, stream=sys.stderr):
    1505 """ 1506 Pretty-parse the string. This parses the string, and catches any 1507 warnings or errors produced. Any warnings and errors are 1508 displayed, and the resulting DOM parse structure is returned. 1509 1510 @param str: The string to parse. 1511 @type str: C{string} 1512 @param show_warnings: Whether or not to display non-fatal errors 1513 generated by parsing C{str}. 1514 @type show_warnings: C{boolean} 1515 @param show_errors: Whether or not to display fatal errors 1516 generated by parsing C{str}. 1517 @type show_errors: C{boolean} 1518 @param stream: The stream that warnings and errors should be 1519 written to. 1520 @type stream: C{stream} 1521 @return: a DOM document encoding the contents of C{str}. 1522 @rtype: C{Element} 1523 @raise SyntaxError: If any fatal errors were encountered. 1524 """ 1525 errors = [] 1526 confused = 0 1527 try: 1528 val = parse(str, errors) 1529 warnings = [e for e in errors if not e.is_fatal()] 1530 errors = [e for e in errors if e.is_fatal()] 1531 except: 1532 confused = 1 1533 1534 if not show_warnings: warnings = [] 1535 warnings.sort() 1536 errors.sort() 1537 if warnings: 1538 print >>stream, '='*SCRWIDTH 1539 print >>stream, "WARNINGS" 1540 print >>stream, '-'*SCRWIDTH 1541 for warning in warnings: 1542 print >>stream, warning.as_warning() 1543 print >>stream, '='*SCRWIDTH 1544 if errors and show_errors: 1545 if not warnings: print >>stream, '='*SCRWIDTH 1546 print >>stream, "ERRORS" 1547 print >>stream, '-'*SCRWIDTH 1548 for error in errors: 1549 print >>stream, error 1550 print >>stream, '='*SCRWIDTH 1551 1552 if confused: raise 1553 elif errors: raise SyntaxError('Encountered Errors') 1554 else: return val
    1555 1556 ################################################## 1557 ## Parse Errors 1558 ################################################## 1559
    1560 -class TokenizationError(ParseError):
    1561 """ 1562 An error generated while tokenizing a formatted documentation 1563 string. 1564 """
    1565
    1566 -class StructuringError(ParseError):
    1567 """ 1568 An error generated while structuring a formatted documentation 1569 string. 1570 """
    1571
    1572 -class ColorizingError(ParseError):
    1573 """ 1574 An error generated while colorizing a paragraph. 1575 """
    1576 - def __init__(self, descr, token, charnum, is_fatal=1):
    1577 """ 1578 Construct a new colorizing exception. 1579 1580 @param descr: A short description of the error. 1581 @type descr: C{string} 1582 @param token: The token where the error occured 1583 @type token: L{Token} 1584 @param charnum: The character index of the position in 1585 C{token} where the error occured. 1586 @type charnum: C{int} 1587 """ 1588 ParseError.__init__(self, descr, token.startline, is_fatal) 1589 self.token = token 1590 self.charnum = charnum
    1591 1592 CONTEXT_RANGE = 20
    1593 - def descr(self):
    1594 RANGE = self.CONTEXT_RANGE 1595 if self.charnum <= RANGE: 1596 left = self.token.contents[0:self.charnum] 1597 else: 1598 left = '...'+self.token.contents[self.charnum-RANGE:self.charnum] 1599 if (len(self.token.contents)-self.charnum) <= RANGE: 1600 right = self.token.contents[self.charnum:] 1601 else: 1602 right = (self.token.contents[self.charnum:self.charnum+RANGE] 1603 + '...') 1604 return ('%s\n\n%s%s\n%s^' % (self._descr, left, right, ' '*len(left)))
    1605 1606 ################################################## 1607 ## Convenience parsers 1608 ################################################## 1609
    1610 -def parse_as_literal(str):
    1611 """ 1612 Return a DOM document matching the epytext DTD, containing a 1613 single literal block. That literal block will include the 1614 contents of the given string. This method is typically used as a 1615 fall-back when the parser fails. 1616 1617 @param str: The string which should be enclosed in a literal 1618 block. 1619 @type str: C{string} 1620 1621 @return: A DOM document containing C{str} in a single literal 1622 block. 1623 @rtype: C{Element} 1624 """ 1625 return Element('epytext', Element('literalblock', str))
    1626
    1627 -def parse_as_para(str):
    1628 """ 1629 Return a DOM document matching the epytext DTD, containing a 1630 single paragraph. That paragraph will include the contents of the 1631 given string. This can be used to wrap some forms of 1632 automatically generated information (such as type names) in 1633 paragraphs. 1634 1635 @param str: The string which should be enclosed in a paragraph. 1636 @type str: C{string} 1637 1638 @return: A DOM document containing C{str} in a single paragraph. 1639 @rtype: C{Element} 1640 """ 1641 return Element('epytext', Element('para', str))
    1642 1643 ################################################################# 1644 ## SUPPORT FOR EPYDOC 1645 ################################################################# 1646
    1647 -def parse_docstring(docstring, errors, **options):
    1648 """ 1649 Parse the given docstring, which is formatted using epytext; and 1650 return a C{ParsedDocstring} representation of its contents. 1651 @param docstring: The docstring to parse 1652 @type docstring: C{string} 1653 @param errors: A list where any errors generated during parsing 1654 will be stored. 1655 @type errors: C{list} of L{ParseError} 1656 @param options: Extra options. Unknown options are ignored. 1657 Currently, no extra options are defined. 1658 @rtype: L{ParsedDocstring} 1659 """ 1660 return ParsedEpytextDocstring(parse(docstring, errors), **options)
    1661
    1662 -class ParsedEpytextDocstring(ParsedDocstring):
    1663 SYMBOL_TO_HTML = { 1664 # Symbols 1665 '<-': '&larr;', '->': '&rarr;', '^': '&uarr;', 'v': '&darr;', 1666 1667 # Greek letters 1668 'alpha': '&alpha;', 'beta': '&beta;', 'gamma': '&gamma;', 1669 'delta': '&delta;', 'epsilon': '&epsilon;', 'zeta': '&zeta;', 1670 'eta': '&eta;', 'theta': '&theta;', 'iota': '&iota;', 1671 'kappa': '&kappa;', 'lambda': '&lambda;', 'mu': '&mu;', 1672 'nu': '&nu;', 'xi': '&xi;', 'omicron': '&omicron;', 1673 'pi': '&pi;', 'rho': '&rho;', 'sigma': '&sigma;', 1674 'tau': '&tau;', 'upsilon': '&upsilon;', 'phi': '&phi;', 1675 'chi': '&chi;', 'psi': '&psi;', 'omega': '&omega;', 1676 'Alpha': '&Alpha;', 'Beta': '&Beta;', 'Gamma': '&Gamma;', 1677 'Delta': '&Delta;', 'Epsilon': '&Epsilon;', 'Zeta': '&Zeta;', 1678 'Eta': '&Eta;', 'Theta': '&Theta;', 'Iota': '&Iota;', 1679 'Kappa': '&Kappa;', 'Lambda': '&Lambda;', 'Mu': '&Mu;', 1680 'Nu': '&Nu;', 'Xi': '&Xi;', 'Omicron': '&Omicron;', 1681 'Pi': '&Pi;', 'Rho': '&Rho;', 'Sigma': '&Sigma;', 1682 'Tau': '&Tau;', 'Upsilon': '&Upsilon;', 'Phi': '&Phi;', 1683 'Chi': '&Chi;', 'Psi': '&Psi;', 'Omega': '&Omega;', 1684 1685 # HTML character entities 1686 'larr': '&larr;', 'rarr': '&rarr;', 'uarr': '&uarr;', 1687 'darr': '&darr;', 'harr': '&harr;', 'crarr': '&crarr;', 1688 'lArr': '&lArr;', 'rArr': '&rArr;', 'uArr': '&uArr;', 1689 'dArr': '&dArr;', 'hArr': '&hArr;', 1690 'copy': '&copy;', 'times': '&times;', 'forall': '&forall;', 1691 'exist': '&exist;', 'part': '&part;', 1692 'empty': '&empty;', 'isin': '&isin;', 'notin': '&notin;', 1693 'ni': '&ni;', 'prod': '&prod;', 'sum': '&sum;', 1694 'prop': '&prop;', 'infin': '&infin;', 'ang': '&ang;', 1695 'and': '&and;', 'or': '&or;', 'cap': '&cap;', 'cup': '&cup;', 1696 'int': '&int;', 'there4': '&there4;', 'sim': '&sim;', 1697 'cong': '&cong;', 'asymp': '&asymp;', 'ne': '&ne;', 1698 'equiv': '&equiv;', 'le': '&le;', 'ge': '&ge;', 1699 'sub': '&sub;', 'sup': '&sup;', 'nsub': '&nsub;', 1700 'sube': '&sube;', 'supe': '&supe;', 'oplus': '&oplus;', 1701 'otimes': '&otimes;', 'perp': '&perp;', 1702 1703 # Alternate (long) names 1704 'infinity': '&infin;', 'integral': '&int;', 'product': '&prod;', 1705 '<=': '&le;', '>=': '&ge;', 1706 } 1707 1708 SYMBOL_TO_LATEX = { 1709 # Symbols 1710 '<-': r'\(\leftarrow\)', '->': r'\(\rightarrow\)', 1711 '^': r'\(\uparrow\)', 'v': r'\(\downarrow\)', 1712 1713 # Greek letters (use lower case when upcase not available) 1714 1715 'alpha': r'\(\alpha\)', 'beta': r'\(\beta\)', 'gamma': 1716 r'\(\gamma\)', 'delta': r'\(\delta\)', 'epsilon': 1717 r'\(\epsilon\)', 'zeta': r'\(\zeta\)', 'eta': r'\(\eta\)', 1718 'theta': r'\(\theta\)', 'iota': r'\(\iota\)', 'kappa': 1719 r'\(\kappa\)', 'lambda': r'\(\lambda\)', 'mu': r'\(\mu\)', 1720 'nu': r'\(\nu\)', 'xi': r'\(\xi\)', 'omicron': r'\(o\)', 'pi': 1721 r'\(\pi\)', 'rho': r'\(\rho\)', 'sigma': r'\(\sigma\)', 'tau': 1722 r'\(\tau\)', 'upsilon': r'\(\upsilon\)', 'phi': r'\(\phi\)', 1723 'chi': r'\(\chi\)', 'psi': r'\(\psi\)', 'omega': 1724 r'\(\omega\)', 1725 1726 'Alpha': r'\(\alpha\)', 'Beta': r'\(\beta\)', 'Gamma': 1727 r'\(\Gamma\)', 'Delta': r'\(\Delta\)', 'Epsilon': 1728 r'\(\epsilon\)', 'Zeta': r'\(\zeta\)', 'Eta': r'\(\eta\)', 1729 'Theta': r'\(\Theta\)', 'Iota': r'\(\iota\)', 'Kappa': 1730 r'\(\kappa\)', 'Lambda': r'\(\Lambda\)', 'Mu': r'\(\mu\)', 1731 'Nu': r'\(\nu\)', 'Xi': r'\(\Xi\)', 'Omicron': r'\(o\)', 'Pi': 1732 r'\(\Pi\)', 'ho': r'\(\rho\)', 'Sigma': r'\(\Sigma\)', 'Tau': 1733 r'\(\tau\)', 'Upsilon': r'\(\Upsilon\)', 'Phi': r'\(\Phi\)', 1734 'Chi': r'\(\chi\)', 'Psi': r'\(\Psi\)', 'Omega': 1735 r'\(\Omega\)', 1736 1737 # HTML character entities 1738 'larr': r'\(\leftarrow\)', 'rarr': r'\(\rightarrow\)', 'uarr': 1739 r'\(\uparrow\)', 'darr': r'\(\downarrow\)', 'harr': 1740 r'\(\leftrightarrow\)', 'crarr': r'\(\hookleftarrow\)', 1741 'lArr': r'\(\Leftarrow\)', 'rArr': r'\(\Rightarrow\)', 'uArr': 1742 r'\(\Uparrow\)', 'dArr': r'\(\Downarrow\)', 'hArr': 1743 r'\(\Leftrightarrow\)', 'copy': r'{\textcopyright}', 1744 'times': r'\(\times\)', 'forall': r'\(\forall\)', 'exist': 1745 r'\(\exists\)', 'part': r'\(\partial\)', 'empty': 1746 r'\(\emptyset\)', 'isin': r'\(\in\)', 'notin': r'\(\notin\)', 1747 'ni': r'\(\ni\)', 'prod': r'\(\prod\)', 'sum': r'\(\sum\)', 1748 'prop': r'\(\propto\)', 'infin': r'\(\infty\)', 'ang': 1749 r'\(\angle\)', 'and': r'\(\wedge\)', 'or': r'\(\vee\)', 'cap': 1750 r'\(\cap\)', 'cup': r'\(\cup\)', 'int': r'\(\int\)', 'there4': 1751 r'\(\therefore\)', 'sim': r'\(\sim\)', 'cong': r'\(\cong\)', 1752 'asymp': r'\(\approx\)', 'ne': r'\(\ne\)', 'equiv': 1753 r'\(\equiv\)', 'le': r'\(\le\)', 'ge': r'\(\ge\)', 'sub': 1754 r'\(\subset\)', 'sup': r'\(\supset\)', 'nsub': r'\(\supset\)', 1755 'sube': r'\(\subseteq\)', 'supe': r'\(\supseteq\)', 'oplus': 1756 r'\(\oplus\)', 'otimes': r'\(\otimes\)', 'perp': r'\(\perp\)', 1757 1758 # Alternate (long) names 1759 'infinity': r'\(\infty\)', 'integral': r'\(\int\)', 'product': 1760 r'\(\prod\)', '<=': r'\(\le\)', '>=': r'\(\ge\)', 1761 } 1762
    1763 - def __init__(self, dom_tree, **options):
    1764 self._tree = dom_tree 1765 # Caching: 1766 self._html = self._latex = self._plaintext = None 1767 self._terms = None 1768 # inline option -- mark top-level children as inline. 1769 if options.get('inline') and self._tree is not None: 1770 for elt in self._tree.children: 1771 elt.attribs['inline'] = True
    1772
    1773 - def __str__(self):
    1774 return str(self._tree)
    1775
    1776 - def to_html(self, docstring_linker, directory=None, docindex=None, 1777 context=None, **options):
    1778 if self._html is not None: return self._html 1779 if self._tree is None: return '' 1780 indent = options.get('indent', 0) 1781 self._html = self._to_html(self._tree, docstring_linker, directory, 1782 docindex, context, indent) 1783 return self._html
    1784
    1785 - def to_latex(self, docstring_linker, **options):
    1786 if self._latex is not None: return self._latex 1787 if self._tree is None: return '' 1788 indent = options.get('indent', 0) 1789 self._hyperref = options.get('hyperref', 1) 1790 self._latex = self._to_latex(self._tree, docstring_linker, indent) 1791 return self._latex
    1792
    1793 - def to_plaintext(self, docstring_linker, **options):
    1794 # [XX] don't cache -- different options might be used!! 1795 #if self._plaintext is not None: return self._plaintext 1796 if self._tree is None: return '' 1797 if 'indent' in options: 1798 self._plaintext = to_plaintext(self._tree, 1799 indent=options['indent']) 1800 else: 1801 self._plaintext = to_plaintext(self._tree) 1802 return self._plaintext
    1803
    1804 - def _index_term_key(self, tree):
    1805 str = to_plaintext(tree) 1806 str = re.sub(r'\s\s+', '-', str) 1807 return "index-"+re.sub("[^a-zA-Z0-9]", "_", str)
    1808
    1809 - def _to_html(self, tree, linker, directory, docindex, context, 1810 indent=0, seclevel=0):
    1811 if isinstance(tree, basestring): 1812 return plaintext_to_html(tree) 1813 1814 if tree.tag == 'epytext': indent -= 2 1815 if tree.tag == 'section': seclevel += 1 1816 1817 # Process the variables first. 1818 variables = [self._to_html(c, linker, directory, docindex, context, 1819 indent+2, seclevel) 1820 for c in tree.children] 1821 1822 # Construct the HTML string for the variables. 1823 childstr = ''.join(variables) 1824 1825 # Perform the approriate action for the DOM tree type. 1826 if tree.tag == 'para': 1827 return wordwrap( 1828 (tree.attribs.get('inline') and '%s' or '<p>%s</p>') % childstr, 1829 indent) 1830 elif tree.tag == 'code': 1831 style = tree.attribs.get('style') 1832 if style: 1833 return '<code class="%s">%s</code>' % (style, childstr) 1834 else: 1835 return '<code>%s</code>' % childstr 1836 elif tree.tag == 'uri': 1837 return ('<a href="%s" target="_top">%s</a>' % 1838 (variables[1], variables[0])) 1839 elif tree.tag == 'link': 1840 return linker.translate_identifier_xref(variables[1], variables[0]) 1841 elif tree.tag == 'italic': 1842 return '<i>%s</i>' % childstr 1843 elif tree.tag == 'math': 1844 return '<i class="math">%s</i>' % childstr 1845 elif tree.tag == 'indexed': 1846 term = Element('epytext', *tree.children, **tree.attribs) 1847 return linker.translate_indexterm(ParsedEpytextDocstring(term)) 1848 #term_key = self._index_term_key(tree) 1849 #return linker.translate_indexterm(childstr, term_key) 1850 elif tree.tag == 'bold': 1851 return '<b>%s</b>' % childstr 1852 elif tree.tag == 'ulist': 1853 return '%s<ul>\n%s%s</ul>\n' % (indent*' ', childstr, indent*' ') 1854 elif tree.tag == 'olist': 1855 start = tree.attribs.get('start') or '' 1856 return ('%s<ol start="%s">\n%s%s</ol>\n' % 1857 (indent*' ', start, childstr, indent*' ')) 1858 elif tree.tag == 'li': 1859 return indent*' '+'<li>\n%s%s</li>\n' % (childstr, indent*' ') 1860 elif tree.tag == 'heading': 1861 return ('%s<h%s class="heading">%s</h%s>\n' % 1862 ((indent-2)*' ', seclevel, childstr, seclevel)) 1863 elif tree.tag == 'literalblock': 1864 return '<pre class="literalblock">\n%s\n</pre>\n' % childstr 1865 elif tree.tag == 'doctestblock': 1866 return doctest_to_html(tree.children[0].strip()) 1867 elif tree.tag == 'fieldlist': 1868 raise AssertionError("There should not be any field lists left") 1869 elif tree.tag in ('epytext', 'section', 'tag', 'arg', 1870 'name', 'target', 'html'): 1871 return childstr 1872 elif tree.tag == 'symbol': 1873 symbol = tree.children[0] 1874 return self.SYMBOL_TO_HTML.get(symbol, '[%s]' % symbol) 1875 elif tree.tag == 'graph': 1876 # Generate the graph. 1877 graph = self._build_graph(variables[0], variables[1:], linker, 1878 docindex, context) 1879 if not graph: return '' 1880 # Write the graph. 1881 image_url = '%s.gif' % graph.uid 1882 image_file = os.path.join(directory, image_url) 1883 return graph.to_html(image_file, image_url) 1884 else: 1885 raise ValueError('Unknown epytext DOM element %r' % tree.tag)
    1886 1887 #GRAPH_TYPES = ['classtree', 'packagetree', 'importgraph']
    1888 - def _build_graph(self, graph_type, graph_args, linker, 1889 docindex, context):
    1890 # Generate the graph 1891 if graph_type == 'classtree': 1892 from epydoc.apidoc import ClassDoc 1893 if graph_args: 1894 bases = [docindex.find(name, context) 1895 for name in graph_args] 1896 elif isinstance(context, ClassDoc): 1897 bases = [context] 1898 else: 1899 log.warning("Could not construct class tree: you must " 1900 "specify one or more base classes.") 1901 return None 1902 from epydoc.docwriter.dotgraph import class_tree_graph 1903 return class_tree_graph(bases, linker, context) 1904 elif graph_type == 'packagetree': 1905 from epydoc.apidoc import ModuleDoc 1906 if graph_args: 1907 packages = [docindex.find(name, context) 1908 for name in graph_args] 1909 elif isinstance(context, ModuleDoc): 1910 packages = [context] 1911 else: 1912 log.warning("Could not construct package tree: you must " 1913 "specify one or more root packages.") 1914 return None 1915 from epydoc.docwriter.dotgraph import package_tree_graph 1916 return package_tree_graph(packages, linker, context) 1917 elif graph_type == 'importgraph': 1918 from epydoc.apidoc import ModuleDoc 1919 modules = [d for d in docindex.root if isinstance(d, ModuleDoc)] 1920 from epydoc.docwriter.dotgraph import import_graph 1921 return import_graph(modules, docindex, linker, context) 1922 1923 elif graph_type == 'callgraph': 1924 if graph_args: 1925 docs = [docindex.find(name, context) for name in graph_args] 1926 docs = [doc for doc in docs if doc is not None] 1927 else: 1928 docs = [context] 1929 from epydoc.docwriter.dotgraph import call_graph 1930 return call_graph(docs, docindex, linker, context) 1931 else: 1932 log.warning("Unknown graph type %s" % graph_type)
    1933 1934
    1935 - def _to_latex(self, tree, linker, indent=0, seclevel=0, breakany=0):
    1936 if isinstance(tree, basestring): 1937 return plaintext_to_latex(tree, breakany=breakany) 1938 1939 if tree.tag == 'section': seclevel += 1 1940 1941 # Figure out the child indent level. 1942 if tree.tag == 'epytext': cindent = indent 1943 else: cindent = indent + 2 1944 variables = [self._to_latex(c, linker, cindent, seclevel, breakany) 1945 for c in tree.children] 1946 childstr = ''.join(variables) 1947 1948 if tree.tag == 'para': 1949 return wordwrap(childstr, indent)+'\n' 1950 elif tree.tag == 'code': 1951 return '\\texttt{%s}' % childstr 1952 elif tree.tag == 'uri': 1953 if len(variables) != 2: raise ValueError('Bad URI ') 1954 if self._hyperref: 1955 # ~ and # should not be escaped in the URI. 1956 uri = tree.children[1].children[0] 1957 uri = uri.replace('{\\textasciitilde}', '~') 1958 uri = uri.replace('\\#', '#') 1959 if variables[0] == variables[1]: 1960 return '\\href{%s}{\\textit{%s}}' % (uri, variables[1]) 1961 else: 1962 return ('%s\\footnote{\\href{%s}{%s}}' % 1963 (variables[0], uri, variables[1])) 1964 else: 1965 if variables[0] == variables[1]: 1966 return '\\textit{%s}' % variables[1] 1967 else: 1968 return '%s\\footnote{%s}' % (variables[0], variables[1]) 1969 elif tree.tag == 'link': 1970 if len(variables) != 2: raise ValueError('Bad Link') 1971 return linker.translate_identifier_xref(variables[1], variables[0]) 1972 elif tree.tag == 'italic': 1973 return '\\textit{%s}' % childstr 1974 elif tree.tag == 'math': 1975 return '\\textit{%s}' % childstr 1976 elif tree.tag == 'indexed': 1977 term = Element('epytext', *tree.children, **tree.attribs) 1978 return linker.translate_indexterm(ParsedEpytextDocstring(term)) 1979 elif tree.tag == 'bold': 1980 return '\\textbf{%s}' % childstr 1981 elif tree.tag == 'li': 1982 return indent*' ' + '\\item ' + childstr.lstrip() 1983 elif tree.tag == 'heading': 1984 return ' '*(indent-2) + '(section) %s\n\n' % childstr 1985 elif tree.tag == 'doctestblock': 1986 return doctest_to_latex(tree.children[0].strip()) 1987 elif tree.tag == 'literalblock': 1988 return '\\begin{alltt}\n%s\\end{alltt}\n\n' % childstr 1989 elif tree.tag == 'fieldlist': 1990 return indent*' '+'{omitted fieldlist}\n' 1991 elif tree.tag == 'olist': 1992 return (' '*indent + '\\begin{enumerate}\n\n' + 1993 ' '*indent + '\\setlength{\\parskip}{0.5ex}\n' + 1994 childstr + 1995 ' '*indent + '\\end{enumerate}\n\n') 1996 elif tree.tag == 'ulist': 1997 return (' '*indent + '\\begin{itemize}\n' + 1998 ' '*indent + '\\setlength{\\parskip}{0.6ex}\n' + 1999 childstr + 2000 ' '*indent + '\\end{itemize}\n\n') 2001 elif tree.tag == 'symbol': 2002 symbol = tree.children[0] 2003 return self.SYMBOL_TO_LATEX.get(symbol, '[%s]' % symbol) 2004 elif tree.tag == 'graph': 2005 return '(GRAPH)' 2006 #raise ValueError, 'graph not implemented yet for latex' 2007 else: 2008 # Assume that anything else can be passed through. 2009 return childstr
    2010 2011 _SUMMARY_RE = re.compile(r'(\s*[\w\W]*?\.)(\s|$)') 2012
    2013 - def summary(self):
    2014 if self._tree is None: return self, False 2015 tree = self._tree 2016 doc = Element('epytext') 2017 2018 # Find the first paragraph. 2019 variables = tree.children 2020 while (len(variables) > 0) and (variables[0].tag != 'para'): 2021 if variables[0].tag in ('section', 'ulist', 'olist', 'li'): 2022 variables = variables[0].children 2023 else: 2024 variables = variables[1:] 2025 2026 # Special case: if the docstring contains a single literal block, 2027 # then try extracting the summary from it. 2028 if (len(variables) == 0 and len(tree.children) == 1 and 2029 tree.children[0].tag == 'literalblock'): 2030 str = re.split(r'\n\s*(\n|$).*', 2031 tree.children[0].children[0], 1)[0] 2032 variables = [Element('para')] 2033 variables[0].children.append(str) 2034 2035 # If we didn't find a paragraph, return an empty epytext. 2036 if len(variables) == 0: return ParsedEpytextDocstring(doc), False 2037 2038 # Is there anything else, excluding tags, after the first variable? 2039 long_docs = False 2040 for var in variables[1:]: 2041 if isinstance(var, Element) and var.tag == 'fieldlist': 2042 continue 2043 long_docs = True 2044 break 2045 2046 # Extract the first sentence. 2047 parachildren = variables[0].children 2048 para = Element('para', inline=True) 2049 doc.children.append(para) 2050 for parachild in parachildren: 2051 if isinstance(parachild, basestring): 2052 m = self._SUMMARY_RE.match(parachild) 2053 if m: 2054 para.children.append(m.group(1)) 2055 long_docs |= parachild is not parachildren[-1] 2056 if not long_docs: 2057 other = parachild[m.end():] 2058 if other and not other.isspace(): 2059 long_docs = True 2060 return ParsedEpytextDocstring(doc), long_docs 2061 para.children.append(parachild) 2062 2063 return ParsedEpytextDocstring(doc), long_docs
    2064
    2065 - def split_fields(self, errors=None):
    2066 if self._tree is None: return (self, ()) 2067 tree = Element(self._tree.tag, *self._tree.children, 2068 **self._tree.attribs) 2069 fields = [] 2070 2071 if (tree.children and 2072 tree.children[-1].tag == 'fieldlist' and 2073 tree.children[-1].children): 2074 field_nodes = tree.children[-1].children 2075 del tree.children[-1] 2076 2077 for field in field_nodes: 2078 # Get the tag 2079 tag = field.children[0].children[0].lower() 2080 del field.children[0] 2081 2082 # Get the argument. 2083 if field.children and field.children[0].tag == 'arg': 2084 arg = field.children[0].children[0] 2085 del field.children[0] 2086 else: 2087 arg = None 2088 2089 # Process the field. 2090 field.tag = 'epytext' 2091 fields.append(Field(tag, arg, ParsedEpytextDocstring(field))) 2092 2093 # Save the remaining docstring as the description.. 2094 if tree.children and tree.children[0].children: 2095 return ParsedEpytextDocstring(tree), fields 2096 else: 2097 return None, fields
    2098 2099
    2100 - def index_terms(self):
    2101 if self._terms is None: 2102 self._terms = [] 2103 self._index_terms(self._tree, self._terms) 2104 return self._terms
    2105
    2106 - def _index_terms(self, tree, terms):
    2107 if tree is None or isinstance(tree, basestring): 2108 return 2109 2110 if tree.tag == 'indexed': 2111 term = Element('epytext', *tree.children, **tree.attribs) 2112 terms.append(ParsedEpytextDocstring(term)) 2113 2114 # Look for index items in child nodes. 2115 for child in tree.children: 2116 self._index_terms(child, terms)
    2117

    epydoc-3.0.1+dfsg/doc/whatsnew.html0000644000175000017500000003221510750103050017462 0ustar pronovicpronovic Epydoc: What's New

    What's New in Epydoc

    Epydoc 3.0

    Released January, 2008

    Support for Parsing & Introspection

    In previous versions, epydoc extracted information about each module by importing it, and using introspection to examine its contents. Epydoc 3.0 still supports introspection, but is also capable of extracting information about python modules by parsing their source code. Furthermore, the new version of epydoc can combine these two sources of information (introspection & parsing). This is important because each source has its own advantages and disadvantages with respect to the other. See the FAQ for more information about the relative benefits of introspection and parsing, and why it's good to merge information from both sources.

    Docstrings for variables

    Epydoc now supports variable docstrings. If a variable assignment statement is immediately followed by a bare string literal, then that assignment is treated as a docstring for that variable. In classes, variable assignments at the class definition level are considered class variables; and assignments to instance variables in the constructor (__init__) are considered instance variables:

    >>> class A:
    ...     x = 22
    ...     """Docstring for class variable A.x"""
    ...
    ...     def __init__(self, a):
    ...         self.y = a
    ...         """Docstring for instance variable A.y
    

    Variables may also be documented using comment docstrings. If a variable assignment is immediately preceeded by a comment whose lines begin with the special marker "#:", or is followed on the same line by such a comment, then it is treated as a docstring for that variable:

    >>> #: docstring for x
    ... x = 22
    >>> x = 22 #: docstring for x
    

    Graphs & Diagrams

    Epydoc can automatically generate a variety of graphs, including class tress, package trees, uml class graphs, and import graphs. These graphs may be included in the generated output in one of two ways:

    • The --graph option causes epydoc to automatically generate a given type of graph for all applicable modules, classes, or functions. For example, using --graph classtree will replace the text-based class tree with a graphical class tree on all module pages. See the command line interface documentation for more information.
    • Graphs may be explicitly created by docstrings, using appropriate markup. In epytext, graphs are created using the "G" colorization marker (i.e., "G{graphname}", or "G{graphname options...}" for graphs with options). In reStructuredText, graphs are created using custom directives. For more information, see the epytext manual or the notes on using reStructuredText with epydoc. .

    Epydoc can also generate function call graphs, showing the callers and the callees for each function. To generate call graphs, Epydoc uses data produced by a Python profiler such Profile or hotshot.

    For some examples of automatically generated graphs, see the API Documentation for epydoc (including the page for the epydoc.docwriter.dotgraph module).

    Graph generation requires the Graphviz package [download].

    Syntax Highlighted Source Code

    The HTML output now includes source code listings with syntax higlighting, including links from identifiers back into the documentation. For examples of source code pages, see the API Documentation for epydoc (follow the show source link from any documented module, class, or function).

    Improved Output

    • Methods that are inherited from "external" base classes are listed, but no longer described in detail. E.g., if "object" is used as a base class, then the methods inherited from "object" will be listed at the bottom of the method summary table, but not described in detail. Furthermore methods and variables not very detailed (with at most a short docstring) are only shown in the summary, while most detailed items also appear in a full detailed box.
    • The HTML output no longer contains separate pages for including and excluding private variables. Instead, it uses CSS to dynamically hide or display private variables. A cookie is used to record the user's preference. (By default, private variables are hidden.)
    • Additional pages are created, listing identifiers, documented definitions, bugs and to-do items. An optional log page can also be generated, reporting all the errors and warning raised during documentation generation.
    • Improved variable values representation, using the parsed values if the standard representation is not informative (such as <Foo instance at 0x...>). Syntax highlighting is used for introspected values, including colorization for regular expressions.
    • Improved support for adding links into the generated documentation. A new API, epydoc.docwriter.xlink, can be used to determine the correct URL for any object name; and a new redirect page named named "redirect.html" uses javascript to automatically redirect the user to the correct URL for any given object name. See the FAQ for more information.

    Improved Documentation Extraction

    • Proper support for nested classes.
    • Full unicode support, including support for the encoding directive.
    • Variables conventionally used for modules metadata such as __version__ are recognized as modules fields.
    • The __all__ attribute is used to decide whether objects are public or private. If an object is listed in an __all__ list, it will appear defined in that module even if imported from elsewhere, keeping the API safe from implementation changes.
    • Increased robustness in the face of a variety of "magic" manipulations of namespaces.
    • Fine-grained control over exactly which modules should be parsed, introspected, or both.
    • Support for Zope 3.x InterfaceClass and Zope 2.x ExtensionClass objects.

    Epydoc 2.1

    Released March 20, 2004

    New Features

    • Support for Zope ExtensionClasses
    • Updated graphical user interface
    • Added support for modules that define __path__.
    • New documentation fields:
      • @include: Imports the documentation from another object.
      • @undocumented: Don't document the given object(s)
    • Various bug fixes

    Epydoc 2.0

    Released July 22, 2003

    New Features

    Improvements to Docstring processing
    • Support for ReStructuredText docstrings.
    • Support for Javadoc docstrings.
    • Many new documentation fields for docstrings.
    • More robust crossreference link resolving.
    Improvements to Output Generation
    • New output formats: LaTeX, DVI, PostScript, and PDF.
    • Three new formats for displaying inherited methods and variables: listed, grouped, and included.
    Improvements to Inspection
    • Support for new Python 2.2+ objects, including class methods, static methods, properties, and metaclasses.
    • Automatic detection of imported variables.
    • Documentation inheritance for inherited methods and variables.
    Improvements to Efficiency
    • Epydoc 2.0 runs 50%-200% faster than epydoc 1.1. (e.g., it runs 160% faster when documenting the Python standard library).

    Changes

    • Support for ReStructuredText docstrings.
    • Support for Javadoc docstrings.
    • Many new documentation fields for docstrings.
    • More robust crossreference link resolving.
    • New output formats: LaTeX, DVI, PostScript, and PDF.
    • Three new formats for displaying inherited methods and variables: listed, grouped, and included.
    • Support for new Python 2.2+ objects, including class methods, static methods, properties, and metaclasses.
    • Automatic detection of imported variables.
    • Documentation inheritance for inherited methods and variables.
    • Epydoc 2.0 runs 50%-200% faster than epydoc 1.1. (e.g., it runs 160% faster when documenting the Python standard library).
    • The new "markup" package provides a simple interface makes it easy to add support for additional markup languages.
    • __extra_epydoc_fields__ and @newfield can be used to define new fields.
    • If the directory for a package is specified, then automatically document all of its contents.
    • Increased contrast of "blue" and "green" stylesheet
    • Added --test option, to control what tests are run for --check.
    • Consolidated error reporting for failed crossreference links and overridden parameter mismatches.
    • Added --ignore-param-mismatch option, which supresses warnings about parameter mismatches
    • Fixed bug in path magic for epydoc.py and epydoc.pyw scripts
    • Replaced __epydoc_sort__ with @sort
    • Changes to epytext:
      • Epytext now supports symbols (S{...})
      • Epydoc allows multi-word values for field arguments (eg for group names)
      • Fixeded several minor bugs
    • --show-imports now lists imported vars & modules
    • Improvements to error reporting
    • Improved sorting
    • Many bug fixes
    • General code clean-up
    • Added preliminary and partial implementation for man-style output (like pydoc)
    • Changed the definition of the --navlink parameter, to allow for more flexible encoding of the homepage link.
    • Improvements to HTML output.
      • Display variable values in variable summary table
      • Added tooltips for variable values, that show a more complete value (up to 600 characters)
      • Minor tweaks & improvements
      • In the table of contents, only list objects from modules that were explicitly documented (don't list base classes from imported modules, etc)

    Older Releases

    See the Release Notes on SourceForge.

    epydoc-3.0.1+dfsg/doc/manual-docstring.html0000644000175000017500000001620210750103050021067 0ustar pronovicpronovic Python Docstrings

    Python Docstrings

    Python documentation strings (or docstrings) provide a convenient way of associating documentation with Python modules, functions, classes, and methods. An object's docsting is defined by including a string constant as the first statement in the object's definition. For example, the following function defines a docstring:

    def x_intercept(m, b):
        """
        Return the x intercept of the line y=m*x+b.  The x intercept of a
        line is the point at which it crosses the x axis (y=0).
        """
        return -b/m

    Docstrings can be accessed from the interpreter and from Python programs using the "__doc__" attribute:

    >>> print x_intercept.__doc__
        Return the x intercept of the line y=m*x+b.  The x intercept of a
        line is the point at which it crosses the x axis (y=0).

    The pydoc module, which became part of the standard library in Python 2.1, can be used to display information about a Python object, including its docstring:

    >>> from pydoc import help
    
    >>> help(x_intercept)
    Help on function x_intercept in module __main__:
    
    x_intercept(m, b)
        Return the x intercept of the line y=m*x+b.  The x intercept of a
        line is the point at which it crosses the x axis (y=0).

    For more information about Python docstrings, see the Python Tutorial or the O'Reilly Network article Python Documentation Tips and Tricks.

    Variable docstrings

    Python don't support directly docstrings on variables: there is no attribute that can be attached to variables and retrieved interactively like the __doc__ attribute on modules, classes and functions.

    While the language doesn't directly provides for them, Epydoc supports variable docstrings: if a variable assignment statement is immediately followed by a bare string literal, then that assignment is treated as a docstring for that variable. In classes, variable assignments at the class definition level are considered class variables; and assignments to instance variables in the constructor (__init__) are considered instance variables:

    class A:
        x = 22
        """Docstring for class variable A.x"""
    
        def __init__(self, a):
            self.y = a
            """Docstring for instance variable A.y

    Variables may also be documented using comment docstrings. If a variable assignment is immediately preceeded by a comment whose lines begin with the special marker '#:', or is followed on the same line by such a comment, then it is treated as a docstring for that variable:

    #: docstring for x
    x = 22
    x = 22 #: docstring for x

    Notice that variable docstrings are only available for documentation when the source code is available for parsing: it is not possible to retrieve variable

    Items visibility

    Any Python object (modules, classes, functions, variables...) can be public or private. Usually the object name decides the object visibility: objects whose name starts with an underscore and doesn't end with an underscore are considered private. All the other objects (including the "magic functions" such as __add__) are public.

    For each module and class, Epydoc generates pages with both public and private methods. A Javascript snippet allows you to toggle the visibility of private objects.

    If a module wants to hide some of the objects it contains (either defined in the module itself or imported from other modules), it can explicitly list the names if its public names in the __all__ variable.

    If a module defines the __all__ variable, Epydoc uses its content to decide if the module objects are public or private.

    epydoc-3.0.1+dfsg/doc/manual-usage.html0000644000175000017500000006050010750103050020177 0ustar pronovicpronovic Using Epydoc

    Using Epydoc

    Epydoc provides two user interfaces:

    • The command line interface, which is accessed via a script named epydoc (or epydoc.py on Windows)
    • The graphical interface, which is accessed via a script named epydocgui (or epydoc.pyw on Windows).

    Epydoc can also be accessed programmatically; see epydoc's API documentation for more information.

    The Command Line Interface

    The epydoc script extracts API documentation for a set of Python objects, and writes it using a selected output format. Objects can be named using dotted names, module filenames, or package directory names. (On Windows, this script is named epydoc.py.)

    Command Line Usage (Abbreviated)

    epydoc [--html|--pdf] [-o DIR] [--parse-only|--introspect-only] [-v|-q]
           [--name NAME] [--url URL] [--docformat NAME] [--graph GRAPHTYPE]
           [--inheritance STYLE] [--config FILE] OBJECTS...
    
    OBJECTS...
    A list of the Python objects that should be documented. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages.
    --html Generate HTML output. (default)
    --pdf Generate Adobe Acrobat (PDF) output, using LaTeX.
    -o DIR, --output DIR, --target DIR
     The output directory.
    --parse-only, --introspect-only
     By default, epydoc will gather information about each Python object using two methods: parsing the object's source code; and importing the object and directly introspecting it. Epydoc combines the information obtained from these two methods to provide more complete and accurate documentation. However, if you wish, you can tell epydoc to use only one or the other of these methods. For example, if you are running epydoc on untrusted code, you should use the --parse-only option.
    -v, -q Increase (-v) or decrease (-q) the verbosity of the output. These options may be repeated to further increase or decrease verbosity. Docstring markup warnings are supressed unless -v is used at least once.
    --name NAME The documented project's name.
    --url URL The documented project's URL.
    --docformat NAME
     The markup language that should be used by default to process modules' docstrings. This is only used for modules that do not define the special __docformat__ variable; it is recommended that you explicitly specify __docformat__ in all your modules.
    --graph GRAPHTYPE
     

    Include graphs of type GRAPHTYPE in the generated output. Graphs are generated using the Graphviz dot executable. If this executable is not on the path, then use --dotpath to specify its location. This option may be repeated to include multiple graph types in the output. To include all graphs, use --graph all. The available graph types are:

    • classtree: displays each class's base classes and subclasses;
    • callgraph: displays the callers and callees of each function or method. These graphs are based on profiling information, which must be specified using the --pstate option.
    • umlclass: displays each class's base classes and subclasses, using UML style. Methods and attributes are listed in the classes where they are defined. If type information is available about attributes (via the @type field), then those types are displayed as separate classes, and the attributes are displayed as associations.
    --inheritance STYLE
     

    The format that should be used to display inherited methods, variables, and properties. Currently, three styles are supported. To see an example of each style, click on it:

    • grouped: Inherited objects are gathered into groups, based on which class they are inherited from.
    • listed: Inherited objects are listed in a short list at the end of the summary table.
    • included: Inherited objects are mixed in with non-inherited objects.
    --config FILE Read the given configuration file, which can contain both options and Python object names. This option may be used multiple times, if you wish to use multiple configuration files. See Configuration Files for more information.

    The complete list of command line options is available in the Command Line Usage section.

    Examples

    The following command will generate HTML documentation for the sys module, and write it to the directory sys_docs:

    [epydoc]$ epydoc --html sys -o sys_docs
    

    The following commands are used to produce the API documentation for epydoc itself. The first command writes html output to the directory html/api, using epydoc as the project name and http://epydoc.sourcforge.net as the project URL. The white CSS style is used; inheritance is displayed using the listed style; and all graphs are included in the output. The second command writes pdf output to the file api.pdf in the directory latex/api, using Epydoc as the project name.

    [epydoc]$ epydoc -v -o html/api --name epydoc --css white \
                     --url http://epydoc.sourceforge.net \
                     --inheritance listed --graph all src/epydoc
    [epydoc]$ epydoc -v -o latex/api --pdf --name "Epydoc" src/epydoc
    

    Configuration Files

    Configuration files, specified using the --config option, may be used to specify both the list of objects to document, and the options that should be used to document them. Configuration files are read using the standard ConfigParser module. The following is a simple example of a configuration file.

    [epydoc] # Epydoc section marker (required by ConfigParser)
    
    # Information about the project.
    name: My Cool Project
    url: http://cool.project/
    
    # The list of modules to document.  Modules can be named using
    # dotted names, module filenames, or package directory names.
    # This option may be repeated.
    modules: sys, os.path, re
    modules: my/project/driver.py
    
    # Write html output to the directory "apidocs"
    output: html
    target: apidocs/
    
    # Include all automatically generated graphs.  These graphs are
    # generated using Graphviz dot.
    graph: all
    dotpath: /usr/local/bin/dot
    

    A more complete example, including all of the supported options, is also available.

    The Graphical Interface

    Epydoc also includes a graphical interface, for systems where command line interfaces are not convenient (such as Windows). The graphical interface can be invoked with the epydocgui command, or with epydoc.pyw in the Scripts subdirectory of the Python installation directory under Windows. Currently, the graphical interface can only generate HTML output.

    epydoc_gui.png

    Use the Add box to specify what objects you wish to document. Objects can be specified using dotted names (such as os.path), module filenames (such as epydoc/epytext.py), or package directory names (such as epydoc/). Packages are expanded to include all sub-modules and sub-packages. Once you have added all of the modules that you wish to document, press the Start button. Epydoc's progress will be displayed on the progress bar.

    To customize the output, click on the Options arrow at the bottom of the window. This opens the options pane, which contains fields corresponding to each command line option.

    epydoc_guiconfig.png

    The epydoc graphical interface can save and load project files, which record the set of modules and the options that you have selected. Select File->Save to save the current modules and options to a project file; and File->Open to open a previously saved project file. (These project files do not currently use the same format as the configuration files used by the command line interface.)

    For more information, see the epydocgui(1) man page.

    Documentation Completeness Checks

    The epydoc script can be used to check the completeness of the reference documentation. In particular, it will check that every module, class, method, and function has a description; that every parameter has a description and a type; and that every variable has a type. If the -p option is used, then these checks are run on both public and private objects; otherwise, the checks are only run on public objects.

    epydoc --check [-p] MODULES...

    MODULES...
    A list of the modules that should be checked. Modules may be specified using either filenames (such as epydoc/epytext.py) or module names (such as os.path). The filename for a package is its __init__.py file.
    -p Run documentation completeness checks on private objects.

    For each object that fails a check, epydoc will print a warning. For example, some of the warnings generated when checking the completeness of the documentation for epydoc's private objects are:

    epydoc.html.HTML_Doc._dom_link_to_html........No docs
    epydoc.html.HTML_Doc._module..................No type
    epydoc.html.HTML_Doc._link_to_html.link.......No descr
    epydoc.html.HTML_Doc._author.return...........No type
    epydoc.html.HTML_Doc._author.authors..........No descr, No type
    epydoc.html.HTML_Doc._author.container........No descr, No type
    epydoc.html.HTML_Doc._base_tree.uid...........No descr, No type
    epydoc.html.HTML_Doc._base_tree.width.........No descr, No type
    epydoc.html.HTML_Doc._base_tree.postfix.......No descr, No type
    

    If you'd like more fine-grained control over what gets checked, or you would like to check other fields (such as the author or version), then you should use the DocChecker class directly.

    HTML Files

    Every Python module and class is documented in its own file. Index files, tree files, a help file, and a frames-based table of contents are also created. The following list describes each of the files generated by epydoc:

    index.html
    The standard entry point for the documentation. Normally, index.html is a copy of the frames file (frames.html). But if the --no-frames option is used, then index.html is a copy of the API documentation home page, which is normally the documentation page for the top-level package or module (or the trees page if there is no top-level package or module).
    module-module.html
    The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
    class-class.html
    The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType.
    module-pysrc.html
    A page with the module colorized source code, with links back to the objects main documentation pages. The creation of the colorized source pages can be controlled using the options --show-sourcecode and --no-sourcecode.
    module-tree.html
    The documented module hierarchy.
    class-tree.html
    The documented classes hierarchy.
    identifier-index.html
    The index of all the identifiers found in the documented items.
    term-index.html
    The index of all the term definition found in the docstrings. Term definitions are created using the Indexed Terms markup.
    bug-index.html
    The index of all the known bug in the documented sources. Bugs are marked using the @bug tag.
    todo-index.html
    The index of all the to-do items in the documented sources. They are marked using the @todo tag.
    help.html
    The help page for the project. This page explains how to use and navigate the webpage produced by epydoc.
    epydoc-log.html
    A page with the log of the epydoc execution. It is available clicking on the timestamp below each page, if the documentation was created using the --include-log option. The page also contains the list of the options enabled when the documentation was created.
    api-objects.txt
    A text file containing each available item and the URL where it is documented. Each item takes a file line and it is separated by the URL by a tab charecter. Such file can be used to create external API links.
    redirect.html
    A page containing Javascript code that redirect the browser to the documentation page indicated by the accessed fragment. For example opening the page redirect.html#epydoc.apidoc.DottedName the browser will be redirected to the page epydoc.apidoc.DottedName-class.html.
    frames.html
    The main frames file. Two frames on the left side of the window contain a table of contents, and the main frame on the right side of the window contains API documentation pages.
    toc.html
    The top-level table of contents page. This page is displayed in the upper-left frame of frames.html, and provides links to the toc-everything.html and toc-module-module.html pages.
    toc-everything.html
    The table of contents for the entire project. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the project.
    toc-module-module.html
    The table of contents for a module. This page is displayed in the lower-left frame of frames.html, and provides links to every class, type, exception, function, and variable defined by the module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
    epydoc.css
    The CSS stylesheet used to display all HTML pages.

    CSS Stylesheets

    Epydoc creates a CSS stylesheet (epydoc.css) when it builds the API documentation for a project. You can specify which stylesheet should be used using the --css command-line option. If you do not specify a stylesheet, and one is already present, epydoc will use that stylesheet; otherwise, it will use the default stylesheet.

    epydoc-3.0.1+dfsg/doc/othermarkup.html0000644000175000017500000001744510750103047020201 0ustar pronovicpronovic Alternate Markup Languages

    Alternate Markup Languages

    Epydoc's default markup language is epytext, a lightweight markup language that's easy to write and to understand. But if epytext is not powerful enough for you, or doesn't suit your needs, epydoc also supports three alternate markup languages:

    • reStructuredText is an "easy-to-read, what-you-see-is-what-you-get plaintext markup syntax." It is more powerful than epytext (e.g., it includes markup for tables and footnotes); but it is also more complex, and sometimes harder to read.
    • Javadoc is a documentation markup language that was developed for Java. It consists of HTML, augmented by a set of special tagged fields.
    • Plaintext docstrings are rendered verbatim (preserving whitespace).

    To specify the markup language for a module, you should define a module-level string variable __docformat__, containing the name of the module's markup language. The name of the markup language may optionally be followed by a language code (such as en for English). Conventionally, the definition of the __docformat__ variable immediately follows the module's docstring:

    # widget.py
    """
    Graphical support for `gizmos` and `widgets`.
    """
    __docformat__ = "restructuredtext en"
    [...]
    

    To change the default markup language from the command line, use the --docformat option. For example, the following command generates API documentation for the existing regular expression package re, which uses plaintext markup:

    [epydoc]$ epydoc --docformat plaintext re
    

    reStructuredText

    reStructuredText is a markup language that was developed in conjunction with Docutils. In order to parse reStructuredText docstrings, Docutils 0.3 or higher must be installed. If Docutils is not installed, then reStructuredText docstrings will be rendered as plaintext. Docutils can be downloaded from the Docutils SourceForge page.

    In addition to the standard set of fields, the reStructruedText parser also supports consolidated fields, which combine the documentation for several objects into a single field. For more information, see the markup-specific notes for reStructuredText fields.

    The epydoc reStructuredText reader also defines several custom directives, which can be used to automatically generate a variety of graphs. The following custom directives are currently defined:

    DirectiveDescription
    .. classtree:: [classes...]
        :dir: up|down|left|right
    
    Display a class hierarchy for the given class or classes (including all superclasses & subclasses). If no class is specified, and the directive is used in a class's docstring, then that class's class hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down).
    .. packagetree:: [modules...]
        :dir: up|down|left|right
        :style: uml|tree
    
    Display a package hierarchy for the given module or modules (including all subpackages and submodules). If no module is specified, and the directive is used in a module's docstring, then that module's package hierarchy will be displayed. The dir option specifies the orientation for the graph (default=down). The style option specifies whether packages should be displayed in a tree, or using nested UML symbols.
    .. importgraph:: [modules...]
        :dir: up|down|left|right
    
    Display an import graph for the given module or modules. If no module is specified, and the directive is used in a module's docstring, then that module's import graph will be displayed. The dir option specifies the orientation for the graph (default=left).
    .. callgraph:: [functions...]
        :dir: up|down|left|right
    
    Display a call graph for the given function or functions. If no function is specified, and the directive is used in a function's docstring, then that function's call graph will be displayed. The dir option specifies the orientation for the graph (default=right).
    .. dotgraph:: [title...]
        :caption: text...
        graph...
    
    Display a custom Graphviz dot graph. The body of the directive (graph...) should contain the body of a dot graph. The optional title argument, if specified, is used as the title of the graph. The optional caption option can be used to provide a caption for the graph.

    Javadoc

    Javadoc is a markup language developed by Sun Microsystems for documenting Java APIs. The epydoc implementation of Javadoc is based on the Javadoc 1.4.2 reference documentation. However, there are likely to be some minor incompatibilities between Sun's implementation and epydoc's. Known incompatibilities include:

    • Epydoc does not support the Javadoc block tag @serial.
    • Epydoc does not support the following Javadoc inline tags: {@docroot}, {@inheritdoc}, {@value}.
    • Epydoc adds many field tags that Sun does not include, such as @var, @type, and @group.
    epydoc-3.0.1+dfsg/doc/custom.css0000644000175000017500000001103610750103047016764 0ustar pronovicpronovic/* :Author: Edward Loper :Copyright: This stylesheet has been placed in the public domain. Stylesheet for use with Docutils. */ @import url("docutils.css"); /*===================================================================*/ /* Navigation box */ table.navbox { border-right: 1px solid black; border-left: 1px solid black; border-bottom: 1px solid black; } td.nav { border: 2px outset #70b0ff; background: #70b0ff; color: black; font-weight: bold; } td.navselect { background: #4888d8; color: white; } a.nav:link { text-decoration: none; } a.nav:visited { text-decoration: none; } /*======================================================================*/ /* Source code colorization */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table.docutils pre.py-doctest { background: #dce4ec; color: #000000; border: 1px solid #708890; } .py-prompt { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050; } .py-name:visited { color: #000050; } .py-number { color: #005000; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /*======================================================================*/ /* Document formatting */ @media screen { body { background: #204060; color: #000000; } div.document { background: white; color: black; padding: 0 1em 0 1em; border: 2px solid black; } } h1.title { font-size: 180%; font-weight: bold; text-align: center; padding: .1em; margin: 0; border-bottom: 2px solid black;} h2.subtitle { font-size: 100%; text-align: center; font-style: italic; font-weight: normal; margin-top: 0; } pre.literal-block { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table.docutils { border: 1px solid black; background: #e8f0f8; margin-top: 6px; border-collapse: collapse; } table.docutils th, table.docutils td { border: 1px solid black; padding: 0 .5em 0 .5em; } table.docutils th { background: #70b0ff; } div.epydoc-usage { border: 1px solid #708890; background: #e8f0f8; margin: 1em; padding: 0.5em} table.option-list { background: none !important; border: 0px solid black; } table.option-list td { border: none !important; } div.note { border: 1px solid black; background: #e8f0f8; margin-top: 6px; border-collapse: collapse; padding: 0 10px 10px 10px; } div.note p.admonition-title { background: #a0f0c0; margin: 0 -10px; padding: 6px 6px 3px 6px; border-bottom: 1px solid black; } #the-epytext-markup-language table.docutils { width: 95%; } table.docutils pre { border: 0px solid black; } div.note { } /* For the "Sections" example in the manual */ p.h1 { font-size: 150%; font-weight: bold; } p.h2 { font-size: 125%; font-weight: bold; } table.docinfo { margin: 0 0 0.5em 0; font-size: 90%; } div.abstract { margin: 0; padding: 0.5em 1em; border: 1px solid black; background: #e8f0f8; color: black; } div.abstract p { margin: 0; } div.abstract p.topic-title { display: none; } #contents { background: #e8f0f8; color: black; border: 1px solid #000000; margin: 1em 0 1em 0; padding: 0 10px 0 10px; } #contents p.topic-title { background: #70b0ff; text-align: center; font-weight: bold; font-size: 125%; margin: 0 -10px 0 -10px; padding: 0 10px 0 10px; border-bottom: 1px solid black; } /*
    Author: Edward Loper
    Version: 3.0b1
    */ epydoc-3.0.1+dfsg/doc/epydocgui-man.html0000644000175000017500000003613610750103047020377 0ustar pronovicpronovic Man page of EPYDOCGUI

    epydocgui (1)

    NAME

    epydocgui - graphical interface to epydoc

    SYNOPSIS

    epydocgui [project.prj | modules...]

    epydoc -h

    epydoc -V

    DESCRIPTION

    epydocgui is a graphical interface to epydoc, which generates API documentation for Python modules and packages, based on their docstrings. A lightweight markup language called epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables.

    The API documentation produced by epydocgui consists of a set of HTML files. Two subdirectories are created for the public and private documentation. Within each subdirectories, every class and module is documented in its own file. An index file, a trees file, and a help file are also created. If you select the frames option, then a frames-based table of contents is also produced.

    OPTIONS

    project.prj The name of a project file that was saved with epydocgui. Project files record a list of related modules, and the options that should be used to generate the documentation for those modules.
    modules...
    The list of the modules that should be documented. Modules can be specified using module names (such as os.path), filenames (such as epydoc/epytext.py), or directory names (such as epydoc/). Directory names specify packages, and are expanded to include all sub-modules and sub-packages.
    -h, --help, --usage, -?
    Display a usage message.
    -V, --version
    Print the version of Epydoc.

    HTML FILES

    The API documentation produced by epydoc consists of the following files:
    index.html
    The standard entry point for the documentation. Normally, index.html is a frame index file, which defines three frames: two frames on the left side of the browser contain a table of contents, and the main frame on the right side of the window contains documentation pages. But if the --no-frames option is used, then index.html will redirect the user to the project's top page.
    m-module.html
    The API documentation for a module. module is the complete dotted name of the module, such as sys or epydoc.epytext.
    c-class.html
    The API documentation for a class, exception, or type. class is the complete dotted name of the class, such as epydoc.epytext.Token or array.ArrayType.
    trees.html
    The module and class hierarchies.
    indices.html
    The term and identifier indices.
    help.html
    The help page for the project. This page explains how to use and navigate the webpage produced by epydoc.
    toc.html
    The top-level table of contents page. This page is displayed in the upper-left frame, and provides links to toc-everything.html and the toc-m-module.html files. toc.html is not generated if the --no-frames option is used.
    toc-everything.html
    The table of contents for the entire project. This page is displayed in the lower-left frame, and provides links to every class, type, exception, function, and variable defined by the project. toc-everything.html is not generated if the --no-frames option is used.
    toc-m-module.html
    The table of contents for a module. This page is displayed in the lower-left frame, and provides links to every class, type, exception, function, and variable defined by the module. module is the complete dotted name of the module, such as sys or epydoc.epytext. toc-m-module.html is not generated if the --no-frames option is used.
    epydoc.css
    The CSS stylesheet used to display all HTML pages.

    By default, epydoc creates two subdirectories in the output directory: public and private. Each directory contains all of the files specified above. But if the --no-private option is used, then no subdirectories are created, and the public documentation is written directly to the output directory. ivided into five categories: import errors; epytext errors; epytext warnings; field warnings; and inspection errors. Whenver epydoc encounters an error, it issues a warning message that describes the error, and attempts to continue generating documentation.

    Import errors indicate that epydoc was unable to import a module. Import errors typically prevent epydoc from generating documentation for the module in question. Epydoc can generate the following import errors:

    Bad module name module
    Epydoc attempted to import module, but module is not a valid name for a Python module.
    Could not find a UID for link-target
    Epydoc was unable to find the object referred to by an inline link construction (L{...}). This is usually caused by a typo in the link.
    Could not import module
    Epydoc attempted to import module, but it failed. This typically occurs when module raises an exception.
    file does not exist
    Epydoc attempted to import the module contained in file, but file does not exist.

    Epytext errors are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring. Epydoc can generate the following epytext errors:

    Bad link target.
    The target specified for an inline link contruction (L{...}) is not well-formed. Link targets must be valid python identifiers.
    Bad uri target.
    The target specified for an inline uri contruction (U{...}) is not well-formed. This typically occurs if inline markup is nested inside the URI target.
    Fields must be at the top level.
    The list of fields (@param, etc.) is contained by some other block structure (such as a list or a section).
    Fields must be the final elements.
    The list of fields (@param, etc.) is not at the end of a docstring.
    Headings must occur at top level.
    The heading is contianed in some other block structure (such as a list).
    Improper doctest block indentation.
    The doctest block dedents past the indentation of its initial prompt line.
    Improper heading indentation.
    The heading for a section is not left-aligned with the paragraphs in the section that contains it.
    Improper paragraph indentation.
    The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext.
    Invalid escape.
    An unknown escape sequence was used with the inline escape construction (E{...}).
    Lists must be indented.
    An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet.
    Unbalanced '{'.
    The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
    Unbalanced '}'.
    The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace).
    Unknown inline markup tag.
    An unknown tag was used with the inline markup construction ( x{...} ).
    Wrong underline character for heading.
    The underline character used for this section heading does not indicate an appopriate section level. The "=" character should be used to underline sections; "-" for subsections; and "~" for subsubsections.

    Epytext warnings are caused by epytext docstrings that contain questionable or suspicious markup. Epytext warnings do not prevent the docstring in question from being parsed. Epydoc can generate the following epytext warnings:

    Possible mal-formatted field item.
    Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (":") is not included in the field tag.
    Possible heading typo.
    Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading.

    Field warnings are caused by epytext docstrings containing invalid fields. The contents of the invalid field are generally ignored. Epydoc can generate the following field warnings:

    @param for unknown parameter param.
    A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
    tag did not expect an argument.
    The field tag tag was used with an argument, but it does not take one.
    tag expected an argument.
    The field tag tag was used without an argument, but it requires one.
    @type for unknown parameter param.
    A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name.
    @type for unknown variable var.
    A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name.
    Unknown field tag tag.
    A docstring contains a field with the unknown tag tag.
    Redefinition of field.
    Multiple field tags define the value of field in the same docstring, but field can only take a single value.

    Inspection errors are generated if epydoc encounters problems while attempting to inspect the properties of a documented object. Most of inspection errors do not prevent epydoc from documenting the object in question. Epydoc can generate the following inspection errors:

    The parameters of inhmethod do not match basemethod.
    The parameters of the undocumented method inhmethod do not match the parameters of the base class method basemethod that it overrides. As a result, inhmethod does not inherit documentation from basemethod. If the difference in parameters is intentional, then you can eliminate the warning by adding a (possibly empty) docstring to inhmethod.
    Docmap cannot add a type
    Epydoc attempted to document an object with an unknown type. This error is typically generated by packages and modules that manipulate the import mechanism, such that importing a module produces some other type of object.
    UID conflict detected: uid
    Two different objects were assigned the same unique identifier by epydoc. This can cause epydoc to substitute the documentation of one object with the documentation of another object that is assigned the same unique identifier. However, this will usually only cause problems if the two objects with the same unique identifiers are both modules or classes, in which case the API documentation page for one object will overwrite the API documentation page for the other object.
    object appears in multiple builtin modules
    While attempting to determine which module defines the builtin object object, epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds.
    object appears in multiple .py modules
    While attempting to determine which module defines the builtin object object, epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds.
    object appears in multiple .so modules
    While attempting to determine which module defines the builtin object object, epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds.
    Could not find a module for object
    Epydoc was unable to determine which module defines object. If object is a function, then this will prevent epydoc from generating any documentation for object, since it does not know what page to put the documentation on. Otherwise, this will prevent the documentation for object from including a link to its containing module.

    AUTHOR

    Epydoc was written by Edward Loper. This man page was originally written by Moshe Zadka, and is currently maintained by Edward Loper.

    BUGS

    Report bugs to <edloper@gradient.cis.upenn.edu>.

    SEE ALSO

    epydoc(1)
    The epydoc webpage
    <http://epydoc.sourceforge.net>
    The epytext markup language manual
    <http://epydoc.sourceforge.net/epytext.html>


    Index

    NAME
    SYNOPSIS
    DESCRIPTION
    OPTIONS
    HTML FILES
    AUTHOR
    BUGS
    SEE ALSO

    This document was created by man2html, using the manual pages.
    Time: 01:20:48 GMT, September 24, 2007
    epydoc-3.0.1+dfsg/doc/docutils.css0000644000175000017500000001241010750103047017275 0ustar pronovicpronovic/* :Author: David Goodger :Contact: goodger@python.org :Date: $Date: 2006-05-21 22:44:42 +0200 (Sun, 21 May 2006) $ :Revision: $Revision: 4564 $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to customize this style sheet. */ /* used to remove borders from tables and images */ .borderless, table.borderless td, table.borderless th { border: 0 } table.borderless td, table.borderless th { /* Override padding for "table.docutils td" with "! important". The right padding separates the table cells. */ padding: 0 0.5em 0 0 ! important } .first { /* Override more specific margin styles with "! important". */ margin-top: 0 ! important } .last, .with-subtitle { margin-bottom: 0 ! important } .hidden { display: none } a.toc-backref { text-decoration: none ; color: black } blockquote.epigraph { margin: 2em 5em ; } dl.docutils dd { margin-bottom: 0.5em } dl.docutils dt { font-weight: bold } div.abstract { margin: 2em 5em } div.abstract p.topic-title { font-weight: bold ; text-align: center } div.admonition, div.attention, div.caution, div.danger, div.error, div.hint, div.important, div.note, div.tip, div.warning { margin: 2em ; border: medium outset ; padding: 1em } div.admonition p.admonition-title, div.hint p.admonition-title, div.important p.admonition-title, div.note p.admonition-title, div.tip p.admonition-title { font-weight: bold ; font-family: sans-serif } div.attention p.admonition-title, div.caution p.admonition-title, div.danger p.admonition-title, div.error p.admonition-title, div.warning p.admonition-title { color: red ; font-weight: bold ; font-family: sans-serif } /* Uncomment (and remove this text!) to get reduced vertical space in compound paragraphs. div.compound .compound-first, div.compound .compound-middle { margin-bottom: 0.5em } div.compound .compound-last, div.compound .compound-middle { margin-top: 0.5em } */ div.dedication { margin: 2em 5em ; text-align: center ; font-style: italic } div.dedication p.topic-title { font-weight: bold ; font-style: normal } div.figure { margin-left: 2em ; margin-right: 2em } div.footer, div.header { clear: both; font-size: smaller } div.line-block { display: block ; margin-top: 1em ; margin-bottom: 1em } div.line-block div.line-block { margin-top: 0 ; margin-bottom: 0 ; margin-left: 1.5em } div.sidebar { margin-left: 1em ; border: medium outset ; padding: 1em ; background-color: #ffffee ; width: 40% ; float: right ; clear: right } div.sidebar p.rubric { font-family: sans-serif ; font-size: medium } div.system-messages { margin: 5em } div.system-messages h1 { color: red } div.system-message { border: medium outset ; padding: 1em } div.system-message p.system-message-title { color: red ; font-weight: bold } div.topic { margin: 2em } h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { margin-top: 0.4em } h1.title { text-align: center } h2.subtitle { text-align: center } hr.docutils { width: 75% } img.align-left { clear: left } img.align-right { clear: right } ol.simple, ul.simple { margin-bottom: 1em } ol.arabic { list-style: decimal } ol.loweralpha { list-style: lower-alpha } ol.upperalpha { list-style: upper-alpha } ol.lowerroman { list-style: lower-roman } ol.upperroman { list-style: upper-roman } p.attribution { text-align: right ; margin-left: 50% } p.caption { font-style: italic } p.credits { font-style: italic ; font-size: smaller } p.label { white-space: nowrap } p.rubric { font-weight: bold ; font-size: larger ; color: maroon ; text-align: center } p.sidebar-title { font-family: sans-serif ; font-weight: bold ; font-size: larger } p.sidebar-subtitle { font-family: sans-serif ; font-weight: bold } p.topic-title { font-weight: bold } pre.address { margin-bottom: 0 ; margin-top: 0 ; font-family: serif ; font-size: 100% } pre.literal-block, pre.doctest-block { margin-left: 2em ; margin-right: 2em } span.classifier { font-family: sans-serif ; font-style: oblique } span.classifier-delimiter { font-family: sans-serif ; font-weight: bold } span.interpreted { font-family: sans-serif } span.option { white-space: nowrap } span.pre { white-space: pre } span.problematic { color: red } span.section-subtitle { /* font-size relative to parent (h1..h6 element) */ font-size: 80% } table.citation { border-left: solid 1px gray; margin-left: 1px } table.docinfo { margin: 2em 4em } table.docutils { margin-top: 0.5em ; margin-bottom: 0.5em } table.footnote { border-left: solid 1px black; margin-left: 1px } table.docutils td, table.docutils th, table.docinfo td, table.docinfo th { padding-left: 0.5em ; padding-right: 0.5em ; vertical-align: top } table.docutils th.field-name, table.docinfo th.docinfo-name { font-weight: bold ; text-align: left ; white-space: nowrap ; padding-left: 0 } h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { font-size: 100% } ul.auto-toc { list-style-type: none } epydoc-3.0.1+dfsg/doc/future.html0000644000175000017500000000365410750103047017147 0ustar pronovicpronovic Epydoc: Future Directions

    Epydoc: Future Directions

    Short Term

    Epydoc version 3.0 is currently in alpha release. My current plans for the near future include:

    • Improve support for graph generation.
    • Work on plaintext output.
    • Profiling
    • More regression tests
    • Add support for generating indices of bugs, todo items, etc.
    • Add an @ingroup tag.
    • Release epydoc 3.0.

    Long Term

    Things I'd eventually like to see in epydoc include:

    • Change the epytext parser to use simple classes instead of DOM.
    • Output to man (troff)?
    • Output to docbook or directly to pdf?
    epydoc-3.0.1+dfsg/doc/doctest/0002755000175000017500000000000010750103105016401 5ustar pronovicpronovicepydoc-3.0.1+dfsg/doc/doctest/docbuilder.html0000644000175000017500000007375410750103051021421 0ustar pronovicpronovic Regression Testing for epydoc.docbuilder

    Regression Testing for epydoc.docbuilder

    Test Function

    This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses build_doc to build documentation, and pretty prints the resulting ModuleDoc object. The attribs argument specifies which attributes of the APIDoc s should be displayed. The build argument gives the name of a variable in the module whose documentation should be built, instead of bilding docs for the whole module.

    >>> from epydoc.test.util import runbuilder
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Docformat selection

    The docstrings format can be selected using the __docformat__ module variable. In the second example below, where docformat='plaintext', the string "@ivar x: ..." will not be treated as a field, since the docstring format is plaintext.

    >>> runbuilder(s='''
    ...     __docformat__ = 'epytext'
    ...     class Foo:
    ...         """@ivar x: description..."""
    ...     ''',
    ...     build='Foo', attribs='descr variables')
    ClassDoc for epydoc_test.Foo [0]
     +- descr = None
     +- variables
        +- x => VariableDoc for epydoc_test.Foo.x [1]
           +- descr = u'description...\n\n'
    >>> runbuilder(s='''
    ...     __docformat__ = 'plaintext'
    ...     class Foo:
    ...         """@var x: description..."""
    ...     ''',
    ...     build='Foo', attribs='descr variables')
    ClassDoc for epydoc_test.Foo [0]
     +- descr = u'@var x: description...\n'
     +- variables = {}

    Stuff from future doesn't appear as variable.

    >>> runbuilder(s="""
    ...     from __future__ import division
    ...     from pickle import dump
    ...     """,
    ...     attribs='variables value')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- dump => VariableDoc for epydoc_test.dump [1]
           +- value
              +- ValueDoc for pickle.dump [2]

    Specifying constructor signature in class docstring

    The class signature can be specified in the class docstring instead of __init__

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         @param a: init param.
    ...         @ivar a: instance var.
    ...         @type a: date
    ...         """
    ...         def __init__(self, a):
    ...             """The ctor docstring."""
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
        |  +- name = '__init__'
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.__init__ [2]
        |        +- arg_descrs = [([u'a'], ...
        |        +- arg_types = {u'a': ...
        |        +- kwarg = None
        |        +- posargs = ['self', 'a']
        |        +- vararg = None
        +- a => VariableDoc for epydoc_test.Foo.a [3]
           +- name = u'a'
           +- value = <UNKNOWN>

    Also keywords arguments can be put in the constructor

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         @keyword a: a kwarg.
    ...         @type a: str
    ...         """
    ...         def __init__(self, **kwargs):
    ...             """The ctor docstring."""
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
           +- name = '__init__'
           +- value
              +- RoutineDoc for epydoc_test.Foo.__init__ [2]
                 +- arg_descrs = [([u'a'], ...
                 +- arg_types = {u'a': ...
                 +- kwarg = 'kwargs'
                 +- posargs = ['self']
                 +- vararg = None

    A missing docstring on the __init__ is not an issue.

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         @param a: a param.
    ...         @type a: str
    ...         """
    ...         def __init__(self, a):
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
           +- name = '__init__'
           +- value
              +- RoutineDoc for epydoc_test.Foo.__init__ [2]
                 +- arg_descrs = [([u'a'], ...
                 +- arg_types = {u'a': ...
                 +- kwarg = None
                 +- posargs = ['self', 'a']
                 +- vararg = None

    Exceptions can be put in the docstring class, and they are assigned to the constructor too.

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """Foo(x, y)
    ...
    ...         A class to ship rockets in outer space.
    ...
    ...         @param x: first param
    ...         @param y: second param
    ...         @except ValueError: frobnication error
    ...         """
    ...         def __init__(self, a, b):
    ...             """__init__ doc"""
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value exception_descrs "
    ...         "posargs vararg kwarg type arg_types arg_descrs docstring")
    ClassDoc for epydoc_test.Foo [0]
     +- docstring = u'A class to ship rockets in outer sp...
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
           +- docstring = <UNKNOWN>
           +- name = '__init__'
           +- value
              +- RoutineDoc for epydoc_test.Foo.__init__ [2]
                 +- arg_descrs = [([u'x'], u'first param'), ([u'y'], u...
                 +- arg_types = {}
                 +- docstring = u'__init__ doc'
                 +- exception_descrs = [(DottedName(u'ValueError'), <epydoc....
                 +- kwarg = None
                 +- posargs = [u'x', u'y']
                 +- vararg = None

    Epydoc can also grok the constructor signature from the class docstring

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """Foo(x, y)
    ...
    ...         A class to ship rockets in outer space.
    ...
    ...         @param x: first param
    ...         @param y: second param
    ...         """
    ...         def __init__(self, a, b):
    ...             """__init__ doc"""
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type arg_types arg_descrs docstring")
    ClassDoc for epydoc_test.Foo [0]
     +- docstring = u'A class to ship rockets ...
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
           +- docstring = <UNKNOWN>
           +- name = '__init__'
           +- value
              +- RoutineDoc for epydoc_test.Foo.__init__ [2]
                 +- arg_descrs = [([u'x'], ...
                 +- arg_types = {}
                 +- docstring = u'__init__ doc'
                 +- kwarg = None
                 +- posargs = [u'x', u'y']
                 +- vararg = None

    A type can apply to both a param and a variable

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         @param a: init param.
    ...         @ivar a: instance var.
    ...         @type a: date
    ...         """
    ...         def __init__(self, a):
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type_descr arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
        |  +- name = '__init__'
        |  +- type_descr = None
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.__init__ [2]
        |        +- arg_descrs = [([u'a'], u'init param.')]
        |        +- arg_types = {u'a': u'date'}
        |        +- kwarg = None
        |        +- posargs = ['self', 'a']
        |        +- vararg = None
        +- a => VariableDoc for epydoc_test.Foo.a [3]
           +- name = u'a'
           +- type_descr = u'date\n\n'
           +- value = <UNKNOWN>

    But there can also be two different types

    >>> runbuilder(s='''
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         @param a: init param.
    ...         @type a: string
    ...         @ivar a: instance var.
    ...         @type a: date
    ...         """
    ...         def __init__(self, a):
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value "
    ...         "posargs vararg kwarg type_descr arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
        |  +- name = '__init__'
        |  +- type_descr = None
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.__init__ [2]
        |        +- arg_descrs = [([u'a'], u'init param.')]
        |        +- arg_types = {u'a': u'string'}
        |        +- kwarg = None
        |        +- posargs = ['self', 'a']
        |        +- vararg = None
        +- a => VariableDoc for epydoc_test.Foo.a [3]
           +- name = u'a'
           +- type_descr = u'date\n\n'
           +- value = <UNKNOWN>

    Value Representation

    Currently, many variable reprs use the introspected form where it would really be better to use the parsed version. See SF bug #1653577. We intend to improve on this. This test documents the current behavior; but should be replaced when we change the behavior.

    >>> from epydoc.test.util import buildvaluedoc
    >>> from epydoc.compat import *
    >>> def print_py_reprs(s):
    ...     value_doc = buildvaluedoc(s)
    ...     print 'Var  Score  Repr\n'+'-'*50
    ...     for (name, var_doc) in sorted(value_doc.variables.items()):
    ...         if len(name) > 1: continue
    ...         var_repr =  var_doc.value.pyval_repr()
    ...         print " %s   %4s   %r" % (name, var_repr.score,
    ...                                  var_repr.to_plaintext(None))
    >>> print_py_reprs('''
    ...     import re
    ...     class Foo: pass
    ...     class Bar:
    ...         def __repr__(self): return "<specialized repr>"
    ...     class Baz:
    ...         def __repr__(self): raise ValueError()
    ...     a = Foo()                  # pyval score < 0; use parse repr.
    ...     b = Bar()                  # pyval score > 0; use pyval repr.
    ...     c = Baz()                  # pyval score < 0; use parse repr.
    ...     d = [1, 2, 3]              # pyval score > 0; use pyval repr.
    ...     d.append(99)
    ...     e = 3+5                    # pyval score > 0; use pyval repr.
    ...     f = re.compile('hi+')      # pyval score > 0; use pyval repr.
    ...     globals()['h'] = Baz()     # pyval score < 0; can't be parsed.
    ...     i = [Foo(), 1, 2]          # pyval score < 0; use parse repr.
    ...     j = [Foo(), 1, 2, 3]       # pyval score = 0; use pyval repr.
    ...     ''')
    Var  Score  Repr
    --------------------------------------------------
     a      0   u'Foo()'
     b      1   u'<specialized repr>'
     c      0   u'Baz()'
     d      5   u'[1, 2, 3, 99]'
     e      1   u'8'
     f      1   u"re.compile(r'hi+')"
     h    -99   u'??'
     i      0   u'[Foo(), 1, 2]'
     j      0   u'[<epydoc_test.Foo instance at ...>, 1, 2, 3]'

    Merging is_imported

    When we do both parsing & introspection, and merge the result, we should trust the introspected APIDoc's is_imported value more than the parsed APIDoc. In particular, in the following example, x should have is_imported=True. But if we can't tell from introspection, then use parse info -- so y should be imported, but z should not.

    >>> import epydoc.docintrospecter
    >>> epydoc.docintrospecter.clear_cache()
    >>> runbuilder(s='''
    ...     import cStringIO
    ...     from re import MULTILINE as y
    ...     x = cStringIO
    ...     z = y
    ...     ''', attribs=("variables is_imported "))
    ModuleDoc for epydoc_test [0]
     +- variables
        +- cStringIO => VariableDoc for epydoc_test.cStringIO [1]
        |  +- is_imported = True
        +- x => VariableDoc for epydoc_test.x [2]
        |  +- is_imported = True
        +- y => VariableDoc for epydoc_test.y [3]
        |  +- is_imported = True
        +- z => VariableDoc for epydoc_test.z [4]
           +- is_imported = False

    Merging the right value

    Test for the SF bug #1678046. Check that, in case of mismatch between parsed and introspected versions of a value, other values don't get damaged.

    >>> runbuilder(s='''
    ...     foo = None
    ...     bar = None
    ...
    ...     def mangle():
    ...         global foo
    ...         foo = 'foo'
    ...
    ...     mangle()
    ... ''',
    ... build="bar",
    ... attribs="pyval")
    GenericValueDoc [0]
     +- pyval = None
    epydoc-3.0.1+dfsg/doc/doctest/epytext.html0000644000175000017500000007574610750103051021012 0ustar pronovicpronovic Regression Testing for epytext

    Regression Testing for epytext

    These tests were taken pretty much verbatim out of the old unittests from epydoc 2.1. They could use some serious updating, when I get the time, esp. given that it's so much easier to write tests with doctest than it was with unittest.

    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()
    >>> from epydoc.markup import epytext
    >>> import re
    >>> def testparse(s):
    ...     # this strips off the <epytext>...</epytext>
    ...     out = ''.join([str(n) for n in
    ...                    epytext.parse(s).children])
    ...     # This is basically word-wrapping:
    ...     out = re.sub(r'((</\w+>)+)', r'\1\n', out).rstrip()
    ...     out = re.sub(r'(?m)^(.{50,70}>)(.)', r'\1\n\2', out).rstrip()
    ...     return out
    >>> def checkparse(s, expect):
    ...     # this strips off the <epytext>...</epytext>
    ...     got = ''.join([str(n) for n in epytext.parse(s).children])
    ...     if got != expect:
    ...         raise ValueError('mismatch: %r %r' % (expect, got))

    Paragraphs:

    >>> print testparse("""
    ...     this is one paragraph.
    ...
    ...     This is
    ...     another.
    ...
    ...     This is a third""")
    <para>this is one paragraph.</para>
    <para>This is another.</para>
    <para>This is a third</para>

    Make sure that unindented fields are allowed:

    >>> print testparse("""
    ...     This is a paragraph.
    ...
    ...     @foo: This is a field.""")
    <para>This is a paragraph.</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>This is a field.</para></field></fieldlist>
    >>> print testparse("""
    ...     This is a paragraph.
    ...     @foo: This is a field.""")
    <para>This is a paragraph.</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>This is a field.</para></field></fieldlist>
    >>> print testparse("""
    ...     This is a paragraph.
    ...       @foo: This is a field.
    ...         Hello.""")
    <para>This is a paragraph.</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>This is a field. Hello.</para></field>
    </fieldlist>
    >>> print testparse("""Paragraph\n@foo: field""")
    <para>Paragraph</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>field</para></field></fieldlist>
    >>> print testparse("""Paragraph\n\n@foo: field""")
    <para>Paragraph</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>field</para></field></fieldlist>
    >>> print testparse("""\nParagraph\n@foo: field""")
    <para>Paragraph</para>
    <fieldlist><field><tag>foo</tag>
    <para inline=True>field</para></field></fieldlist>

    Make sure thta unindented lists are not allowed:

    >>> print testparse("""
    ...     This is a paragraph.
    ...
    ...     - This is a list item.""")
    Traceback (most recent call last):
    StructuringError: Line 4: Lists must be indented.
    >>> print testparse("""
    ...     This is a paragraph.
    ...     - This is a list item.""")
    Traceback (most recent call last):
    StructuringError: Line 3: Lists must be indented.
    >>> print testparse("""
    ...     This is a paragraph.
    ...       - This is a list item.
    ...         Hello.
    ...         - Sublist item""")
    Traceback (most recent call last):
    StructuringError: Line 5: Lists must be indented.
    >>> print testparse("""
    ...     This is a paragraph.
    ...       - This is a list item.
    ...         Hello.
    ...
    ...         - Sublist item""")
    Traceback (most recent call last):
    StructuringError: Line 6: Lists must be indented.
    >>> print testparse("""Paragraph\n\n- list item""")
    Traceback (most recent call last):
    StructuringError: Line 3: Lists must be indented.
    >>> print testparse("""\nParagraph\n- list item""")
    Traceback (most recent call last):
    StructuringError: Line 3: Lists must be indented.

    Special case if there's text on the same line as the opening quote:

    >>> print testparse("""Paragraph\n- list item""")
    <para>Paragraph</para>
    <ulist><li><para inline=True>list item</para></li></ulist>

    Make sure that indented lists are allowed:

    >>> print testparse('This is a paragraph.\n  - This is a list item.\n'+
    ...           'This is a paragraph')
    <para>This is a paragraph.</para>
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    <para>This is a paragraph</para>
    >>> print testparse('This is a paragraph.\n\n  - This is a list item.'+
    ...           '\n\nThis is a paragraph')
    <para>This is a paragraph.</para>
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    <para>This is a paragraph</para>
    >>> print testparse("""
    ...     This is a paragraph.
    ...
    ...       - This is a list item.
    ...
    ...     This is a paragraph""")
    <para>This is a paragraph.</para>
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    <para>This is a paragraph</para>
    >>> print testparse("""
    ...     This is a paragraph.
    ...
    ...           - This is a list item.
    ...     This is a paragraph""")
    <para>This is a paragraph.</para>
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    <para>This is a paragraph</para>
    >>> print testparse("""
    ...       - This is a list item.""")
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    >>> print testparse("""- This is a list item.""")
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>
    >>> print testparse("""\n- This is a list item.""")
    <ulist><li><para inline=True>This is a list item.</para></li>
    </ulist>

    Basic list tests:

    >>> P1 = "This is a paragraph."
    >>> P2 = "This is a \nparagraph."
    >>> LI1 = "  - This is a list item."
    >>> LI2 = "\n  - This is a list item."
    >>> LI3 = "  - This is a list\n  item."
    >>> LI4 = "\n  - This is a list\n  item."
    >>> PARA = ('<para>This is a paragraph.</para>')
    >>> ONELIST = ('<ulist><li><para inline=True>This is a '+
    ...            'list item.</para></li></ulist>')
    >>> TWOLIST = ('<ulist><li><para inline=True>This is a '+
    ...            'list item.</para></li><li><para inline=True>This is a '+
    ...            'list item.</para></li></ulist>')
    >>> for p in (P1, P2):
    ...     for li1 in (LI1, LI2, LI3, LI4):
    ...         checkparse(li1, ONELIST)
    ...         checkparse('%s\n%s' % (p, li1), PARA+ONELIST)
    ...         checkparse('%s\n%s' % (li1, p), ONELIST+PARA)
    ...         checkparse('%s\n%s\n%s' % (p, li1, p),
    ...                         PARA+ONELIST+PARA)
    ...
    ...         for li2 in (LI1, LI2, LI3, LI4):
    ...             checkparse('%s\n%s' % (li1, li2), TWOLIST)
    ...             checkparse('%s\n%s\n%s' % (p, li1, li2), PARA+TWOLIST)
    ...             checkparse('%s\n%s\n%s' % (li1, li2, p), TWOLIST+PARA)
    ...             checkparse('%s\n%s\n%s\n%s' % (p, li1, li2, p),
    ...                             PARA+TWOLIST+PARA)
    >>> LI5 = "  - This is a list item.\n\n    It contains two paragraphs."
    >>> LI5LIST = ('<ulist><li><para inline=True>This is a list item.</para>'+
    ...            '<para>It contains two paragraphs.</para></li></ulist>')
    >>> checkparse(LI5, LI5LIST)
    >>> checkparse('%s\n%s' % (P1, LI5), PARA+LI5LIST)
    >>> checkparse('%s\n%s\n%s' % (P2, LI5, P1), PARA+LI5LIST+PARA)
    >>> LI6 = ("  - This is a list item with a literal block::\n" +
    ...        "    hello\n      there")
    >>> LI6LIST = ('<ulist><li><para inline=True>This is a list item with a literal '+
    ...            'block:</para><literalblock> hello\n   there'+
    ...            '</literalblock></li></ulist>')
    >>> checkparse(LI6, LI6LIST)
    >>> checkparse('%s\n%s' % (P1, LI6), PARA+LI6LIST)
    >>> checkparse('%s\n%s\n%s' % (P2, LI6, P1), PARA+LI6LIST+PARA)

    Item wrap tests:

    >>> LI = "- This is a list\n  item."
    >>> ONELIST = ('<ulist><li><para inline=True>This is a '+
    ...            'list item.</para></li></ulist>')
    >>> TWOLIST = ('<ulist><li><para inline=True>This is a '+
    ...            'list item.</para></li><li><para inline=True>This is a '+
    ...            'list item.</para></li></ulist>')
    >>> for indent in ('', '  '):
    ...     for nl1 in ('', '\n'):
    ...         checkparse(nl1+indent+LI, ONELIST)
    ...         for nl2 in ('\n', '\n\n'):
    ...             checkparse(nl1+indent+LI+nl2+indent+LI, TWOLIST)

    Summary

    The implementation of the summarization function works as expected.

    >>> from epydoc.markup import epytext
    >>> def getsummary(s):
    ...     p = epytext.parse_docstring(s, [])
    ...     s, o = p.summary()
    ...     s = s.to_plaintext(None).strip()
    ...     return s, o

    Let's not lose anything!

    >>> getsummary("Single line")
    ('Single line', False)
    >>> getsummary("Single line.")
    ('Single line.', False)
    >>> getsummary("""
    ... Single line C{with} period.
    ... """)
    ('Single line with period.', False)
    >>> getsummary("""
    ... Single line C{with }period.
    ...
    ... @type: Also with a tag.
    ... """)
    ('Single line with period.', False)
    >>> getsummary("""
    ... Other lines C{with} period.
    ... This is attached
    ... """)
    ('Other lines with period.', True)
    >>> getsummary("""
    ... Other lines C{with} period.
    ...
    ... This is detached
    ...
    ... @type: Also with a tag.
    ... """)
    ('Other lines with period.', True)
    >>> getsummary("""
    ... Other lines without period
    ... This is attached
    ... """)
    ('Other lines without period This is attached', False)
    >>> getsummary("""
    ... Other lines without period
    ...
    ... This is detached
    ... """)
    ('Other lines without period...', True)

    Literal Braces

    SF bug #1562530 reported some trouble with literal braces. These tests make sure that braces are getting rendered as desired.

    >>> def epytext2html(s):
    ...     errs = []
    ...     v = epytext.parse_docstring(s, errs).to_html(None)
    ...     for err in errs: print err
    ...     return (v or '').rstrip()
    >>> print epytext2html("{1:{2:3}}")
    <p>{1:{2:3}}</p>
    >>> print epytext2html("C{{1:{2:3}}}")
    <p><code>{1:{2:3}}</code></p>
    >>> print epytext2html("{1:C{{2:3}}}")
    <p>{1:<code>{2:3}</code>}</p>
    >>> print epytext2html("{{{}{}}{}}")
    <p>{{{}{}}{}}</p>
    >>> print epytext2html("{{E{lb}E{lb}E{lb}}}")
    <p>{{{{{}}</p>

    Graph Raising

    >>> epytext._x = True
    >>> print testparse("""
    ... Para containing G{classtree} graph.
    ... """)
    <para>Para containing </para>
    <graph>classtree</graph>
    <para> graph.</para>
    >>> print testparse("""
    ... Para B{I{containing C{G{classtree} graph}} inside nested markup}.
    ... """)
    <para>Para <bold><italic>containing <code></code></italic></bold>
    </para>
    <graph>classtree</graph>
    <para><bold><italic><code> graph</code></italic>
     inside nested markup</bold>
    .</para>

    Should we strip the 'inline' from the paras in cases like this:? >>> print testparse(""" ... - List item with G{classtree foo} graph. ... - And with I{nested G{callgraph: zippy} markup} too. ... """) <ulist><li><para inline=True>List item with </para> <graph>classtreefoo</graph> <para inline=True> graph.</para></li> <li><para inline=True>And with <italic>nested </italic> </para> <graph>callgraphzippy</graph> <para inline=True><italic> markup</italic>

    System Message: ERROR/3 (src/epydoc/test/epytext.doctest, line 351)

    Unexpected indentation.
    too.</para></li></ulist>
    epydoc-3.0.1+dfsg/doc/doctest/encoding.html0000644000175000017500000005307010750103051021060 0ustar pronovicpronovic End-to-end Tests for Unicode Encoding

    End-to-end Tests for Unicode Encoding

    Test Function

    The function testencoding is used as an end-to-end test for unicode encodings. It takes a given string, writes it to a python file, and processes that file's documentation. It then generates HTML output from the documentation, extracts all docstrings from the generated HTML output, and displays them. (In order to extract & display all docstrings, it monkey-patches the HMTLwriter.docstring_to_html() method.)

    >>> from epydoc.test.util import testencoding
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Encoding Tests

    This section tests the output for a variety of different encodings. Note that some encodings (such as cp424) are not supported, since the ascii coding directive would result in a syntax error in the new encoding.

    Tests for several Microsoft codepges:

    >>> testencoding('''# -*- coding: cp874 -*-
    ... """abc ABC 123 \x80 \x85"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8230;</p>
    >>> testencoding('''# -*- coding: cp1250 -*-
    ... """abc ABC 123 \x80 \x82 \x84 \x85 \xff"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8218; &#8222; &#8230; &#729;</p>
    >>> testencoding('''# -*- coding: cp1251 -*-
    ... """abc ABC 123 \x80 \x81 \x82 \xff"""
    ... ''')
    <p>abc ABC 123 &#1026; &#1027; &#8218; &#1103;</p>
    >>> testencoding('''# -*- coding: cp1252 -*-
    ... """abc ABC 123 \x80 \x82 \x83 \xff"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8218; &#402; &#255;</p>
    >>> testencoding('''# -*- coding: cp1253 -*-
    ... """abc ABC 123 \x80 \x82 \x83 \xfe"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8218; &#402; &#974;</p>

    Unicode tests:

    >>> utf8_test ='''\
    ... """abc ABC 123
    ...
    ... 0x80-0x7ff range:
    ... \xc2\x80 \xc2\x81 \xdf\xbe \xdf\xbf
    ...
    ... 0x800-0xffff range:
    ... \xe0\xa0\x80 \xe0\xa0\x81 \xef\xbf\xbe \xef\xbf\xbf
    ...
    ... 0x10000-0x10ffff range:
    ... \xf0\x90\x80\x80 \xf0\x90\x80\x81
    ... \xf4\x8f\xbf\xbe \xf4\x8f\xbf\xbf
    ... """\n'''
    >>> utf8_bom = '\xef\xbb\xbf'
    >>> # UTF-8 with a coding directive:
    >>> testencoding("# -*- coding: utf-8 -*-\n"+utf8_test)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> # UTF-8 with a BOM & a coding directive:
    >>> testencoding(utf8_bom+"# -*- coding: utf-8 -*-\n"+utf8_test)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> # UTF-8 with a BOM & no coding directive:
    >>> testencoding(utf8_bom+utf8_test)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>

    Tests for KOI8-R:

    >>> testencoding('''# -*- coding: koi8-r -*-
    ... """abc ABC 123 \x80 \x82 \x83 \xff"""
    ... ''')
    <p>abc ABC 123 &#9472; &#9484; &#9488; &#1066;</p>

    Tests for 'coding' directive on the second line:

    >>> testencoding('''\n# -*- coding: cp1252 -*-
    ... """abc ABC 123 \x80 \x82 \x83 \xff"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8218; &#402; &#255;</p>
    >>> testencoding('''# comment on the first line.\n# -*- coding: cp1252 -*-
    ... """abc ABC 123 \x80 \x82 \x83 \xff"""
    ... ''')
    <p>abc ABC 123 &#8364; &#8218; &#402; &#255;</p>
    >>> testencoding("\n# -*- coding: utf-8 -*-\n"+utf8_test)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding("# comment\n# -*- coding: utf-8 -*-\n"+utf8_test)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>

    Tests for shift-jis

    >>> testencoding('''# -*- coding: shift_jis -*-
    ... """abc ABC 123 \xA1 \xA2 \xA3"""
    ... ''') # doctest: +PYTHON2.4
    abc ABC 123 &#65377; &#65378; &#65379;

    Str/Unicode Test

    Make sure that we use the coding for both str and unicode docstrings.

    >>> testencoding('''# -*- coding: utf-8 -*-
    ... """abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80"""
    ... ''')
    <p>abc ABC 123 &#128; &#2047; &#2048;</p>
    >>> testencoding('''# -*- coding: utf-8 -*-
    ... u"""abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80"""
    ... ''')
    <p>abc ABC 123 &#128; &#2047; &#2048;</p>

    Under special circumstances, we may not be able to tell what the proper encoding for a docstring is. This happens if:

    1. the docstring is only available via introspection.
    2. we are unable to determine what module the object that owns the docstring came from.
    3. the docstring contains non-ascii characters

    Under these circumstances, we issue a warning, and treat the docstring as latin-1. An example of this is a non-unicode docstring for properties:

    >>> testencoding('''# -*- coding: utf-8 -*-
    ... p=property(doc="""\xc2\x80""")
    ... ''') # doctest: +ELLIPSIS
    <property object at ...>'s docstring is not a unicode string, but it contains non-ascii data -- treating it as latin-1.
    &#194;&#128;

    Introspection/Parsing Tests

    This section checks to make sure that both introspection & parsing are getting the right results.

    >>> testencoding("# -*- coding: utf-8 -*-\n"+utf8_test, introspect=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding(utf8_bom+"# -*- coding: utf-8 -*-\n"+utf8_test, introspect=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding(utf8_bom+utf8_test, introspect=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding("# -*- coding: utf-8 -*-\n"+utf8_test, parse=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding(utf8_bom+"# -*- coding: utf-8 -*-\n"+utf8_test, parse=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>
    >>> testencoding(utf8_bom+utf8_test, parse=False)
    <p>abc ABC 123</p>
    <p>0x80-0x7ff range: &#128; &#129; &#2046; &#2047;</p>
    <p>0x800-0xffff range: &#2048; &#2049; &#65534; &#65535;</p>
    <p>0x10000-0x10ffff range: &#65536; &#65537; &#1114110; &#1114111;</p>

    Context checks

    Make sure that docstrings are rendered correctly in different contexts.

    >>> testencoding('''# -*- coding: utf-8 -*-
    ... """
    ... @var x: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ... @group \xc2\x80: x
    ... """
    ... ''')
    abc ABC 123 &#128; &#2047; &#2048;
    >>> testencoding('''# -*- coding: utf-8 -*-
    ... def f(x):
    ...     """
    ...     abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @param x: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @type x: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @return: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @rtype: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @except X: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     """
    ... ''')
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    <p>abc ABC 123 &#128; &#2047; &#2048;</p>
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    >>> testencoding('''# -*- coding: utf-8 -*-
    ... class A:
    ...     """
    ...     abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @ivar x: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @cvar y: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     @type x: abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80
    ...     """
    ...
    ...     z = property(doc=u"abc ABC 123 \xc2\x80 \xdf\xbf \xe0\xa0\x80")
    ... ''')
    abc ABC 123 &#128; &#2047; &#2048;
    <p>abc ABC 123 &#128; &#2047; &#2048;</p>
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    abc ABC 123 &#128; &#2047; &#2048;
    epydoc-3.0.1+dfsg/doc/doctest/pyval_repr.html0000644000175000017500000007510710750103051021462 0ustar pronovicpronovic Regression Testing for epydoc.markup.pyval_repr

    Regression Testing for epydoc.markup.pyval_repr

    >>> from epydoc.markup.pyval_repr import *
    >>> colorizer = PyvalColorizer(linelen=40)
    >>> def color(v, linebreakok=True):
    ...     colorizer = PyvalColorizer(linelen=40, linebreakok=linebreakok)
    ...     pds = colorizer.colorize(v, None)
    ...     s = pds.to_html(None).rstrip()
    ...     if isinstance(s, unicode):
    ...         s = s.encode('ascii', 'xmlcharrefreplace')
    ...     print s

    Simple Types

    Integers, floats, None, and complex numbers get printed using str, with no syntax highlighting:

    >>> color(10)
    10
    >>> color(1./4)
    0.25
    >>> color(None)
    None
    >>> color(100)
    100

    Long ints will get wrapped if they're big enough:

    >>> color(10000000)
    10000000
    >>> color(10**90)
    1000000000000000000000000000000000000000&crarr;
    0000000000000000000000000000000000000000&crarr;
    00000000000
    >>> colorizer = PyvalColorizer(linelen=40)
    >>> print '-'*40+'\n'+colorizer.colorize(10**90).to_plaintext(None)
    ----------------------------------------
    1000000000000000000000000000000000000000\
    0000000000000000000000000000000000000000\
    00000000000

    Strings

    Strings have their quotation marks tagged as 'quote'. Characters are escaped using the 'string-escape' encoding.

    >>> color(''.join([chr(i) for i in range(256)]))
    <code class="variable-quote">'''</code><code class="variable-string">\x00\x01\x02\x03\x04\x05\x06\x07\x08\</code>&crarr;
    <code class="variable-string">t</code>
    <code class="variable-string">\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x</code>&crarr;
    <code class="variable-string">15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x</code>&crarr;
    <code class="variable-string">1f !&quot;#$%&amp;\'()*+,-./0123456789:;&lt;=&gt;?@ABCD</code>&crarr;
    <code class="variable-ellipsis">...</code>

    Currently, the "'" quote is always used, because that's what the 'string-escape' encoding expects.

    >>> color('Hello')
    <code class="variable-quote">'</code><code class="variable-string">Hello</code><code class="variable-quote">'</code>
    >>> color('"Hello"')
    <code class="variable-quote">'</code><code class="variable-string">&quot;Hello&quot;</code><code class="variable-quote">'</code>
    >>> color("'Hello'")
    <code class="variable-quote">'</code><code class="variable-string">\'Hello\'</code><code class="variable-quote">'</code>

    Strings containing newlines are automatically rendered as multiline strings.

    >>> color("This\n  is a multiline\n string!")
    <code class="variable-quote">'''</code><code class="variable-string">This</code>
    <code class="variable-string">  is a multiline</code>
    <code class="variable-string"> string!</code><code class="variable-quote">'''</code>

    Unless we ask for them not to be:

    >>> color("This\n  is a multiline\n string!", linebreakok=False)
    <code class="variable-quote">'</code><code class="variable-string">This\n  is a multiline\n string!</code><code class="variable-quote">'</code>

    Unicode strings are handled properly.

    >>> color(u"Hello world")
    <code class="variable-quote">u'</code><code class="variable-string">Hello world</code><code class="variable-quote">'</code>
    >>> color(u"\uaaaa And \ubbbb")
    <code class="variable-quote">u'</code><code class="variable-string">&#43690; And &#48059;</code><code class="variable-quote">'</code>

    Lists, Tuples, etc.

    Lists, tuples, and sets are all colorized using the same method. The braces and commas are tagged with "op". If the value can fit on the current line, it is displayed on one line. Otherwise, each value is listed on a separate line, indented by the size of the open-bracket.

    >>> color(range(10))
    <code class="variable-group">[</code>0<code class="variable-op">, </code>1<code class="variable-op">, </code>2<code class="variable-op">, </code>3<code class="variable-op">, </code>4<code class="variable-op">, </code>5<code class="variable-op">, </code>6<code class="variable-op">, </code>7<code class="variable-op">, </code>8<code class="variable-op">, </code>9<code class="variable-group">]</code>
    >>> color(range(100))
    <code class="variable-group">[</code>0<code class="variable-op">,</code>
     1<code class="variable-op">,</code>
     2<code class="variable-op">,</code>
     3<code class="variable-op">,</code>
     4<code class="variable-op">,</code>
    <code class="variable-ellipsis">...</code>
    >>> color([1,2,[5,6,[(11,22,33),9],10],11]+[99,98,97,96,95])
    <code class="variable-group">[</code>1<code class="variable-op">,</code>
     2<code class="variable-op">,</code>
     <code class="variable-group">[</code>5<code class="variable-op">, </code>6<code class="variable-op">, </code><code class="variable-group">[</code><code class="variable-group">(</code>11<code class="variable-op">, </code>22<code class="variable-op">, </code>33<code class="variable-group">)</code><code class="variable-op">, </code>9<code class="variable-group">]</code><code class="variable-op">, </code>10<code class="variable-group">]</code><code class="variable-op">,</code>
     11<code class="variable-op">,</code>
     99<code class="variable-op">,</code>
    <code class="variable-ellipsis">...</code>
    >>> color(set(range(20)))
    <code class="variable-group">set([</code>0<code class="variable-op">,</code>
         1<code class="variable-op">,</code>
         2<code class="variable-op">,</code>
         3<code class="variable-op">,</code>
         4<code class="variable-op">,</code>
    <code class="variable-ellipsis">...</code>

    Dictionaries

    Dicts are treated just like lists, except that the ":" is also tagged as "op".

    >>> color({1:33, 2:[1,2,3,{7:'oo'*20}]})
    <code class="variable-group">{</code>1<code class="variable-op">: </code>33<code class="variable-op">,</code>
     2<code class="variable-op">: </code><code class="variable-group">[</code>1<code class="variable-op">,</code>
         2<code class="variable-op">,</code>
         3<code class="variable-op">,</code>
         <code class="variable-group">{</code>7<code class="variable-op">: </code><code class="variable-quote">'</code><code class="variable-string">oooooooooooooooooooooooooooooo</code>&crarr;
    <code class="variable-ellipsis">...</code>

    Regular Expressions

    >>> def textcontent(elt):
    ...     if isinstance(elt, basestring): return elt
    ...     else: return ''.join([textcontent(c) for c in elt.children])
    >>> import re
    >>> def color_re(s, check_roundtrip=True):
    ...     colorizer = PyvalColorizer(linelen=55)
    ...     val = colorizer.colorize(re.compile(s))
    ...     if check_roundtrip:
    ...         assert textcontent(val._tree)[13:-2] == s, val._tree
    ...     print val.to_html(None).rstrip()[13:-2]
    >>> # Literal characters
    >>> color_re(u'abc \t\r\n\f\v \xff \uffff', False)
    abc \t\r\n\f\v \xff \uffff
    >>> color_re(r'\.\^\$\\\*\+\?\{\}\[\]\|\(\)\'')
    \.\^\$\\\*\+\?\{\}\[\]\|\(\)\'
    >>> # Any character & character classes
    >>> color_re(r".\d\D\s\S\w\W\A^$\b\B\Z")
    .\d\D\s\S\w\W\A^$\b\B\Z
    >>> # Branching
    >>> color_re(r"foo|bar")
    foo<code class="re-op">|</code>bar
    >>> # Character classes
    >>> color_re(r"[abcd]")
    <code class="re-group">[</code>abcd<code class="re-group">]</code>
    >>> # Repeats
    >>> color_re(r"a*b+c{4,}d{,5}e{3,9}f?")
    a<code class="re-op">*</code>b<code class="re-op">+</code>c<code class="re-op">{4,}</code>d<code class="re-op">{,5}</code>e<code class="re-op">{3,9}</code>f<code class="re-op">?</code>
    >>> color_re(r"a*?b+?c{4,}?d{,5}?e{3,9}?f??")
    a<code class="re-op">*?</code>b<code class="re-op">+?</code>c<code class="re-op">{4,}?</code>d<code class="re-op">{,5}?</code>e<code class="re-op">{3,9}?</code>f<code class="re-op">??</code>
    >>> # Subpatterns
    >>> color_re(r"(foo (bar) | (baz))")
    <code class="re-group">(</code>foo <code class="re-group">(</code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(</code>baz<code class="re-group">)</code><code class="re-group">)</code>
    >>> color_re(r"(?:foo (?:bar) | (?:baz))")
    <code class="re-group">(?:</code>foo <code class="re-group">(?:</code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(?:</code>baz<code class="re-group">)</code><code class="re-group">)</code>
    >>> color_re("(foo (?P<a>bar) | (?P<boop>baz))")
    <code class="re-group">(</code>foo <code class="re-group">(?P&lt;</code><code class="re-ref">a</code><code class="re-group">&gt;</code>bar<code class="re-group">)</code> <code class="re-op">|</code> <code class="re-group">(?P&lt;</code><code class="re-ref">boop</code><code class="re-group">&gt;</code>baz<code class="re-group">)</code><code class="re-group">)</code>
    >>> # Group References
    >>> color_re(r"(...) and (\1)")
    <code class="re-group">(</code>...<code class="re-group">)</code> and <code class="re-group">(</code><code class="re-ref">\1</code><code class="re-group">)</code>
    >>> # Ranges
    >>> color_re(r"[a-bp-z]")
    <code class="re-group">[</code>a<code class="re-op">-</code>bp<code class="re-op">-</code>z<code class="re-group">]</code>
    >>> color_re(r"[^a-bp-z]")
    <code class="re-group">[</code><code class="re-op">^</code>a<code class="re-op">-</code>bp<code class="re-op">-</code>z<code class="re-group">]</code>
    >>> color_re(r"[^abc]")
    <code class="re-group">[</code><code class="re-op">^</code>abc<code class="re-group">]</code>
    >>> # Lookahead/behinds
    >>> color_re(r"foo(?=bar)")
    foo<code class="re-group">(?=</code>bar<code class="re-group">)</code>
    >>> color_re(r"foo(?!bar)")
    foo<code class="re-group">(?!</code>bar<code class="re-group">)</code>
    >>> color_re(r"(?<=bar)foo")
    <code class="re-group">(?&lt;=</code>bar<code class="re-group">)</code>foo
    >>> color_re(r"(?<!bar)foo")
    <code class="re-group">(?&lt;!</code>bar<code class="re-group">)</code>foo
    >>> # Flags
    >>> color_re(r"(?im)^Food")
    <code class="re-flags">(?im)</code>^Food
    >>> color_re(r"(?Limsx)^Food")
    <code class="re-flags">(?Limsx)</code>^Food
    >>> color_re(r"(?Limstux)^Food")
    <code class="re-flags">(?Limstux)</code>^Food
    >>> color_re(r"(?x)This   is   verbose", False)
    <code class="re-flags">(?x)</code>Thisisverbose

    Line Wrapping

    If a line goes beyond linelen, it is wrapped using &crarr; (which gets translated to \\ by ParsedEpytextDocstring.to_plaintext()).

    >>> colorizer = PyvalColorizer(linelen=40)
    >>> print colorizer.colorize('x'*100).to_plaintext(None)
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxx'

    Check that the last line gets a &crarr; when maxlines is exceeded:

    >>> print colorizer.colorize('x'*1000).to_plaintext(None)
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\
    ...

    If linebreakok is False, then line wrapping gives an ellipsis instead:

    >>> colorizer = PyvalColorizer(linelen=40, linebreakok=False)
    >>> print colorizer.colorize('x'*100).to_plaintext(None)
    'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...

    Representation Scores

    When colorized representations are built, a score is computed evaluating how helpful the repr is. E.g., unhelpful values like <Foo instance at 0x12345> get low scores. Currently, the scoring algorithm is:

    • [+1] for each object colorized. When the colorizer recurses into a structure, this will add one for each element contained.
    • [-5] when repr(obj) looks like <xyz instance at ...>, for any colorized object (including objects in structures).
    • [-100] if repr(obj) raises an exception, for any colorized object (including objects in structures).

    The min_score arg to colorize can be used to set a cutoff-point for scores; if the score is too low, then PyvalColorizer.colorize will return None.

    >>> def color2(v):
    ...     colorizer = PyvalColorizer(linelen=40)
    ...     pds = colorizer.colorize(v)
    ...     print 'repr: %s' % pds.to_plaintext(None)
    ...     print 'score: %s (%s)' % (pds.score, pds.score>0 and 'ok' or 'bad')
    >>> class A: pass
    >>> color2('hello')
    repr: 'hello'
    score: 1 (ok)
    >>> color2(["hello", 123])
    repr: ['hello', 123]
    score: 3 (ok)
    >>> color2(A()) # doctest: +ELLIPSIS
    repr: <__builtin__.A instance at ...>
    score: -4 (bad)
    >>> color2([A()]) # doctest: +ELLIPSIS
    repr: [<__builtin__.A instance at ...>]
    score: -3 (bad)
    >>> color2([A(),1,2,3,4,5,6]) # doctest: +ELLIPSIS
    repr: [<__builtin__.A instance at ...>,
     1,
     2,
     3,
     4,
    ...
    score: 1 (ok)
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Summary

    To generate summary-reprs, use maxlines=1 and linebreakok=False:

    >>> summarizer = PyvalColorizer(linelen=60, maxlines=1, linebreakok=False)
    >>> def summarize(v):
    ...     print summarizer.colorize(v).to_plaintext(None)
    >>> summarize(range(100))
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16...
    >>> summarize('hello\nworld')
    'hello\nworld'
    >>> summarize('hello\nworld'*100)
    'hello\nworldhello\nworldhello\nworldhello\nworldhello\nw...
    epydoc-3.0.1+dfsg/doc/doctest/plaintext.html0000644000175000017500000001452610750103051021305 0ustar pronovicpronovic Regression Testing for plaintext

    Regression Testing for plaintext

    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Summary

    The implementation of the summaization function works as expected.

    >>> from epydoc.markup import plaintext
    >>> def getsummary(s):
    ...     p = plaintext.parse_docstring(s, [])
    ...     s, o = p.summary()
    ...     s = s.to_plaintext(None).strip()
    ...     return s, o

    Let's not lose anything!

    >>> getsummary("Single line")
    ('Single line', False)
    >>> getsummary("Single line.")
    ('Single line.', False)
    >>> getsummary("""
    ... Single line with period.
    ... """)
    ('Single line with period.', False)
    >>> getsummary("""
    ... Other lines with period.
    ... This is attached
    ... """)
    ('Other lines with period.', True)
    >>> getsummary("""
    ... Other lines with period.
    ...
    ... This is detached
    ... """)
    ('Other lines with period.', True)
    >>> getsummary("""
    ... Other lines without period
    ... This is attached
    ... """)
    ('Other lines without period...', True)
    >>> getsummary("""
    ... Other lines without period
    ...
    ... This is detached
    ... """)
    ('Other lines without period...', True)

    In 3.0beta1 docstrings such this were not correctly summarized.

    >>> getsummary("""A user-defined wrapper around string objects
    ...
    ... Note: string objects have grown methods in Python 1.6
    ... This module requires Python 1.6 or later.
    ... """)
    ('A user-defined wrapper around string objects', True)
    >>> getsummary("""This is more tricky
    ... than the test before
    ...
    ... but i am looking for the same bug.
    ... """)
    ('This is more tricky\nthan the test before', True)
    epydoc-3.0.1+dfsg/doc/doctest/zope3.html0000644000175000017500000000755610750103051020342 0ustar pronovicpronovic Regression Testing for Zope 3 support

    Regression Testing for Zope 3 support

    RequireModule:

    zope.interface

    >>> from epydoc.test.util import runintrospecter

    We treat zope interface objects as if they were classes:

    >>> runintrospecter(s='''
    ...     from zope.interface import Interface, Attribute
    ...     class IExample(Interface):
    ...         """This interface represents a generic example."""
    ...
    ...         text = Attribute("The text of the example")
    ...
    ...         def setText(text):
    ...             "This method writes the passed text to the text attribute."
    ...
    ...         def getText():
    ...             "This method returns the value of the text attribute."
    ...     ''', attribs='pyval canonical_name', introspect='IExample')
    ClassDoc for epydoc_test.IExample [0]
     +- canonical_name = DottedName('epydoc_test', 'IExample')
     +- pyval = <InterfaceClass epydoc_test.IExample>

    (If we didn't add special support, IExample would be a GenericValueDoc.)

    epydoc-3.0.1+dfsg/doc/doctest/index.html0000644000175000017500000000622710750103047020410 0ustar pronovicpronovic Epydoc: Regression Tests

    Epydoc: Regression Tests

    The following files contain the current regression test suite for epydoc. Each file contains a prose description of some aspect of epydoc, interspersed with doctest examples. Each of these doctest examples is a single test case.

    Regression Tests

    • APIDoc -- The classes used to encode API documentation about Python programs.
    • Introspection -- Extracting API information about Python objects by directly introspecting their values.
    • Source Code Parsing -- Extracting API information about Python objects by parsing their source code.
    • Documentation building -- Merging different information sources into a single API hypertext.
    • Unicode & Encodings -- Tests for the processing of Python files that use non-ascii encodings.
    • Epytext -- Tests for epytext, the default markup language used by epydoc.
    • Javadoc -- Tests for epydoc's support of the Javadoc markup language.
    • Plaintext -- Tests for epydoc's support of plaintext markup.
    • reStructuredText -- Tests for epydoc's support of the reStructuredText markup language.
    • Value Representations -- Tests for epydoc's formatting & syntax highlighting of variable's values.
    • Zope 2 -- Tests for epydoc's support for Zope 2.
    • Zope 3 -- Tests for epydoc's support for Zope 3.
    epydoc-3.0.1+dfsg/doc/doctest/docintrospecter.html0000644000175000017500000013137110750103051022502 0ustar pronovicpronovic Regression Testing for epydoc.docintrospecter

    Regression Testing for epydoc.docintrospecter

    The epydoc.docintrospecter module is used to extract API documentation by introspecting Python objects directy. Its primary interface is docintrospecter.introspect_docs(), which takes a Python object, and returns a ValueDoc describing that value.

    Test Function

    This test function takes a string containing the contents of a module. It writes the string contents to a file, imports the file as a module, and uses docintrospecter.introspect_docs to introspect it, and pretty prints the resulting ModuleDoc object. The attribs argument specifies which attributes of the APIDoc`s should be displayed. The ``introspect` argument gives the name of a variable in the module whose value should be introspected, instead of introspecting the whole module.

    >>> from epydoc.test.util import runintrospecter
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Module Variables

    Each variable defined by a module is encoded as a VariableDoc, whose value contains information about the variable's value. This includes any classes, functions, imported variables, and anything else that has an entry in a module's dictionary.

    >>> runintrospecter(s="""
    ...     x = 12
    ...     def f(x): pass
    ...     class A: pass
    ...     from os import listdir, mkdir
    ...     exec("y = 22")
    ...     """, attribs="variables")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
        +- f => VariableDoc for epydoc_test.f [2]
        +- listdir => VariableDoc for epydoc_test.listdir [3]
        +- mkdir => VariableDoc for epydoc_test.mkdir [4]
        +- x => VariableDoc for epydoc_test.x [5]
        +- y => VariableDoc for epydoc_test.y [6]

    If two variables share the same value, then their VariableDocs will share a ValueDoc:

    >>> runintrospecter(s="""
    ...     def f(x): pass
    ...     alias = f
    ...     """, attribs="variables value")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- alias => VariableDoc for epydoc_test.alias [1]
        |  +- value
        |     +- RoutineDoc for epydoc_test.f [2]
        +- f => VariableDoc for epydoc_test.f [3]
           +- value
              +- RoutineDoc for epydoc_test.f [2] (defined above)

    Importing a dotted name creates a variable for the top-level component of the dotted name:

    >>> runintrospecter(s="""
    ...     import os.path
    ...     """, attribs="variables")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- os => VariableDoc for epydoc_test.os [1]

    Since variables are extracted by introspection, only those variables that exist when the module finishes running will be seen. (This is potentially different from epydoc.docparser, which has to guess about which code paths are taken).

    >>> runintrospecter(s="""
    ...     x = 22
    ...     if x<13: y = 32
    ...     else: z = 14
    ...     del x
    ...     """, attribs="variables")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- z => VariableDoc for epydoc_test.z [1]

    Unlike the parser, arbitrary computed values can be extracted:

    >>> runintrospecter(s="""
    ...     def f(x):
    ...         if x>100: return x
    ...         else: return f((x+2)*8/7)
    ...     x = f(12)
    ...     """, attribs="variables value pyval")
    ModuleDoc for epydoc_test [0]
     +- pyval = <module 'epydoc_test' from ...
     +- variables
        +- f => VariableDoc for epydoc_test.f [1]
        |  +- value
        |     +- RoutineDoc for epydoc_test.f [2]
        |        +- pyval = <function f at ...>
        +- x => VariableDoc for epydoc_test.x [3]
           +- value
              +- GenericValueDoc [4]
                 +- pyval = 112

    The introspecter is unable to determine when variables are aliases for other variables, so it always sets is_alias to UNKNOWN:

    >>> runintrospecter(s="""
    ...     x = 22
    ...     y = x
    ...     """, attribs="variables is_alias")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
        |  +- is_alias = <UNKNOWN>
        +- y => VariableDoc for epydoc_test.y [2]
           +- is_alias = <UNKNOWN>

    Similarly, the introspecter can't always tell if a variable was imported or not, so it sets is_imported to UNKNOWN when it can't decide:

    >>> runintrospecter(s="""
    ...     from pickle import dump       # definitely imported
    ...     from pickle import Pickler    # definitely imported
    ...     from pickle import HIGHEST_PROTOCOL   # might be imported
    ...     class A: pass              # definitely not imported
    ...     def f(x): pass             # definitely not imported
    ...     """, attribs="variables is_imported")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
        |  +- is_imported = False
        +- HIGHEST_PROTOCOL => VariableDoc for epydoc_test.HIGHEST_PROTOCOL [2]
        |  +- is_imported = <UNKNOWN>
        +- Pickler => VariableDoc for epydoc_test.Pickler [3]
        |  +- is_imported = True
        +- dump => VariableDoc for epydoc_test.dump [4]
        |  +- is_imported = True
        +- f => VariableDoc for epydoc_test.f [5]
           +- is_imported = False

    Variable Docstrings

    The docintrospecter is unable extract docstrings for variables. These docstrings can only be detected if the docparser is used.

    >>> runintrospecter(s="""
    ...     x = 12
    ...     '''docstring for x.
    ...     (can be multiline)'''""",
    ...     attribs="variables name docstring")
    ModuleDoc for epydoc_test [0]
     +- docstring = None
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = <UNKNOWN>
           +- name = 'x'
    >>> runintrospecter(s="""
    ...     x = 12 #: comment docstring for x""",
    ...     attribs="variables name docstring")
    ModuleDoc for epydoc_test [0]
     +- docstring = None
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = <UNKNOWN>
           +- name = 'x'

    Functions

    Introspected functions are represented by RoutineDoc objects:

    >>> runintrospecter(s="""
    ...     def f(x):
    ...         'docstring for f'
    ...         print 'inside f'
    ...     """, introspect="f", exclude='defining_module')
    RoutineDoc for epydoc_test.f [0]
     +- canonical_name = DottedName('epydoc_test', 'f')
     +- docs_extracted_by = 'introspecter'
     +- docstring = u'docstring for f'
     +- kwarg = None
     +- lineno = 2
     +- posarg_defaults = [None]
     +- posargs = ['x']
     +- pyval = <function f at ...>
     +- vararg = None

    The function's arguments are described by the properties posargs, posarg_defaults, kwarg, and vararg. posargs is a list of argument names (or nested tuples of names, for tuple-unpacking args). posarg_defaults is a list of ValueDocs for default values, corresponding 1:1 with posargs. posarg_defaults is None for arguments with no default value. vararg and kwarg are the names of the variable argument and keyword argument, respectively:

    >>> runintrospecter(s="""
    ...     def f(x, y=22, z=(1,), *v, **kw):
    ...         'docstring for f'
    ...         print 'inside f'
    ...     """, introspect="f", exclude='defining_module')
    RoutineDoc for epydoc_test.f [0]
     +- canonical_name = DottedName('epydoc_test', 'f')
     +- docs_extracted_by = 'introspecter'
     +- docstring = u'docstring for f'
     +- kwarg = 'kw'
     +- lineno = 2
     +- posarg_defaults = [None, <GenericValueDoc 22>, <Generic...
     +- posargs = ['x', 'y', 'z']
     +- pyval = <function f at ...>
     +- vararg = 'v'

    Tuple arguments are encoded as a single ArgDoc with a complex name:

    >>> runintrospecter(s="""
    ...     def f( (x, (y,z)) ): pass""",
    ...     attribs='variables value posargs posarg_defaults vararg kwarg')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- f => VariableDoc for epydoc_test.f [1]
           +- value
              +- RoutineDoc for epydoc_test.f [2]
                 +- kwarg = None
                 +- posarg_defaults = [None]
                 +- posargs = [['x', ['y', 'z']]]
                 +- vararg = None

    Methods

    Note that the first argument (self) is not listed in the description of g(), since it's a bound instance method:

    >>> runintrospecter(s="""
    ...     class A:
    ...         def f(self, x): 'docstring'
    ...     g=A().f
    ...     """, introspect="g", exclude='defining_module')
    RoutineDoc [0]
     +- docs_extracted_by = 'introspecter'
     +- docstring = u'docstring'
     +- kwarg = None
     +- lineno = 3
     +- posarg_defaults = [None]
     +- posargs = ['x']
     +- pyval = <bound method A.f of <epydoc_test.A i...
     +- vararg = None

    Decorators & Wrapper Assignments

    >>> runintrospecter( # doctest: +PYTHON2.4
    ...     s="""
    ...     @classmethod
    ...     def f(cls, x): 'docstring for f'
    ...     """, introspect="f")
    ClassMethodDoc [0]
     +- docs_extracted_by = 'introspecter'
     +- docstring = u'docstring for f'
     +- kwarg = None
     +- lineno = 2
     +- posarg_defaults = [None, None]
     +- posargs = ['cls', 'x']
     +- pyval = <classmethod object at ...>
     +- vararg = None

    Classes

    >>> runintrospecter(s="""
    ...     class A:
    ...         "no bases"
    ...         class Nested: "nested class"
    ...     class B(A): "single base"
    ...     class C(A,B): "multiple bases"
    ...     class D( ((A)) ): "extra parens around base"
    ...     class E(A.Nested): "dotted name"
    ...     class F(((A).Nested)): "parens with dotted name"
    ...     class Z(B.__bases__[0]): "calculated base" # not handled!
    ...     """,
    ...     attribs='variables value bases docstring')
    ModuleDoc for epydoc_test [0]
     +- docstring = None
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.A [2]
        |        +- bases = []
        |        +- docstring = u'no bases'
        |        +- variables
        |           +- Nested => VariableDoc for epydoc_test.A.Nested [3]
        |              +- docstring = <UNKNOWN>
        |              +- value
        |                 +- ClassDoc [4]
        |                    +- bases = []
        |                    +- docstring = u'nested class'
        |                    +- variables = {}
        +- B => VariableDoc for epydoc_test.B [5]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.B [6]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        +- docstring = u'single base'
        |        +- variables = {}
        +- C => VariableDoc for epydoc_test.C [7]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.C [8]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        |  +- ClassDoc for epydoc_test.B [6] (defined above)
        |        +- docstring = u'multiple bases'
        |        +- variables = {}
        +- D => VariableDoc for epydoc_test.D [9]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.D [10]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        +- docstring = u'extra parens around base'
        |        +- variables = {}
        +- E => VariableDoc for epydoc_test.E [11]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.E [12]
        |        +- bases
        |        |  +- ClassDoc [4] (defined above)
        |        +- docstring = u'dotted name'
        |        +- variables = {}
        +- F => VariableDoc for epydoc_test.F [13]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.F [14]
        |        +- bases
        |        |  +- ClassDoc [4] (defined above)
        |        +- docstring = u'parens with dotted name'
        |        +- variables = {}
        +- Z => VariableDoc for epydoc_test.Z [15]
           +- docstring = <UNKNOWN>
           +- value
              +- ClassDoc for epydoc_test.Z [16]
                 +- bases
                 |  +- ClassDoc for epydoc_test.A [2] (defined above)
                 +- docstring = u'calculated base'
                 +- variables = {}

    Some class variable have a special meaning. The __slots__ variable isn't very useful and should be discarded.

    >>> runintrospecter(s="""
    ...     class Foo:
    ...         __slots__ = ['bar']
    ...         def __init__(self):
    ...             self.bar = 0
    ...     """,
    ...     attribs="variables name value")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- Foo => VariableDoc for epydoc_test.Foo [1]
           +- name = 'Foo'
           +- value
              +- ClassDoc for epydoc_test.Foo [2]
                 +- variables
                    +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [3]
                       +- name = '__init__'
                       +- value
                          +- RoutineDoc [4]

    Delete Statements

    Deleting variables:

    >>> runintrospecter(s="""
    ...     x = y = 12
    ...     del y
    ...     """,
    ...     attribs='variables value repr is_alias')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- is_alias = <UNKNOWN>
           +- value
              +- GenericValueDoc [2]

    The right-hand side of a del statement may contain a nested combination of lists, tuples, and parenthases. All variables found anywhere in this nested structure should be deleted:

    >>> runintrospecter(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del a
    ...     del (b)
    ...     del [c]
    ...     del (d,)
    ...     del (((e,)),)
    ...     del [[[[f]]]]
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]
    >>> runintrospecter(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del a,b
    ...     del (c,d)
    ...     del [e,f]
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]
    >>> runintrospecter(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del ((a, (((((b, c)), d), [e]))), f)
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]

    The right-hand side of a del statement may contain a dotted name, in which case the named variable should be deleted from its containing namespace.

    >>> runintrospecter(s="""
    ...     class A: a = b = 1
    ...     del A.a
    ...     """,
    ...     attribs='variables value local_variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- variables
                    +- b => VariableDoc for epydoc_test.A.b [3]
                       +- value
                          +- GenericValueDoc [4]

    Slice deletes:

    >>> runintrospecter(s="""
    ...     a = b = [1,2,3,4]
    ...     del a[2]
    ...     del a[2:]
    ...     del ([b], a[1])
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- a => VariableDoc for epydoc_test.a [1]

    Single-Line Blocks

    >>> runintrospecter(s="""
    ...     class A: 'docstring for A'
    ...
    ...
    ...     """,
    ...     attribs='variables value docstring')
    ModuleDoc for epydoc_test [0]
     +- docstring = None
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- docstring = <UNKNOWN>
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- docstring = u'docstring for A'
                 +- variables = {}

    Imports

    >>> runintrospecter(s="""
    ...     import pickle
    ...     from pickle import dump
    ...     """,
    ...     attribs='variables value is_imported')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- dump => VariableDoc for epydoc_test.dump [1]
        |  +- is_imported = True
        |  +- value
        |     +- ValueDoc for pickle.dump [2]
        +- pickle => VariableDoc for epydoc_test.pickle [3]
           +- is_imported = True
           +- value
              +- ModuleDoc for pickle [4]
                 +- variables = {}
    >>> runintrospecter(s="""
    ...     from __future__ import division
    ...     from pickle import dump
    ...     """,
    ...     attribs='variables value')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- dump => VariableDoc for epydoc_test.dump [1]
           +- value
              +- ValueDoc for pickle.dump [2]

    Unicode

    >>> runintrospecter(s="""
    ...     def f(x):
    ...         u"unicode in docstring: \u1000"
    ...     """, introspect="f", attribs="docstring")
    RoutineDoc for epydoc_test.f [0]
     +- docstring = u'unicode in docstring: \u1000'

    Instance Variables

    DocIntrospecter is unable to discover instance variables:

    >>> runintrospecter(s="""
    ...     class A:
    ...         def __init__(self, x, y):
    ...             self.x = 10
    ...
    ...             self.y = 20 #: docstring for y
    ...
    ...             self.z = 30
    ...             '''docstring for z'''
    ...
    ...     """, introspect="A", attribs="variables")
    ClassDoc for epydoc_test.A [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.A.__init__ [1]

    Assignments Into Namespaces

    >>> runintrospecter(s="""
    ...     class A: pass
    ...     A.x = 22
    ...     """, introspect="A", attribs='variables value local_variables')
    ClassDoc for epydoc_test.A [0]
     +- variables
        +- x => VariableDoc for epydoc_test.A.x [1]
           +- value
              +- GenericValueDoc [2]

    Recursive objects

    >>> x = runintrospecter(s="""
    ...     class A:
    ...         "A base referring to a child"
    ...         b = None
    ...
    ...     class B(A):
    ...         "Its child."
    ...         pass
    ...
    ...     A.b = B
    ...     """, introspect="A", exclude='defining_module')
    ...     # doctest: +ELLIPSIS
    ClassDoc for epydoc_test.A [0]
     +- bases = []
     +- canonical_name = DottedName('epydoc_test', 'A')
     +- docs_extracted_by = 'introspecter'
     +- docstring = u'A base referring to a child'
     +- pyval = <class epydoc_test.A at ...>
     +- subclasses
     |  +- ClassDoc for epydoc_test.B [1]
     |     +- bases
     |     |  +- ClassDoc for epydoc_test.A [0] (defined above)
     |     +- canonical_name = DottedName('epydoc_test', 'B')
     |     +- docs_extracted_by = 'introspecter'
     |     +- docstring = u'Its child.'
     |     +- pyval = <class epydoc_test.B at ...>
     |     +- subclasses = []
     |     +- variables = {}
     +- variables
        +- b => VariableDoc for epydoc_test.A.b [2]
           +- container
           |  +- ClassDoc for epydoc_test.A [0] (defined above)
           +- docs_extracted_by = 'introspecter'
           +- is_public = True
           +- name = 'b'
           +- value
              +- ClassDoc for epydoc_test.B [1] (defined above)

    Closed Bugs

    SF Bug [ 1657050 ] Builtins not resolved in "os"

    If a variable is listed in __all__, then we need to introspect it, even if we know for certain that it's imported. Before this bug was fixed, the following test generated a generic ValueDoc value instead of a RoutineDoc value, because it didn't introspect the value of getcwd.

    >>> x = runintrospecter(s="""
    ...     __all__ = ['getcwd']
    ...     from os import getcwd
    ...     """, attribs='variables value')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- getcwd => VariableDoc for epydoc_test.getcwd [1]
           +- value
              +- RoutineDoc [2]
    epydoc-3.0.1+dfsg/doc/doctest/docparser.html0000644000175000017500000016010210750103051021247 0ustar pronovicpronovic Regression Testing for epydoc.docparser

    Regression Testing for epydoc.docparser

    The epydoc.docparser module is used to extract API documentation by parsing the source code of Python files. Its primary interface is docparser.parse_docs(), which takes a module's filename, and returns a ModuleDoc describing that module and its contents.

    Test Function

    This test function takes a string containing the contents of a module, and writes it to a file, uses docparser.parse_docs() to parse it, and pretty prints the resulting ModuleDoc object. The attribs argument specifies which attributes of the APIDoc`s should be displayed. The ``show` argument, if specifies, gives the name of the object in the module that should be displayed (but the whole module will always be inspected; this just selects what to display).

    >>> from epydoc.test.util import runparser
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Module Variables from Assignment Statements

    Variables are extracted from any assignment statements in the module, including statements contained inside of top-level if statements, for loops, while loops, and try/except/finally blocks. Tuple assignments are unpacked, when possible.

    For simple variable assignments, DocParser creates VariableDoc objects containing the name; a valuedoc with the value (as both an abstract syntax tree and a string representation); and information about whether we think the value was imported; is an alias; and is an instance variable. (For variables generated from module variable assignments, is_imported and is_instvar will always be False.)

    >>> runparser(s="""
    ...     x = 12
    ...     y = [1,2,3] + [4,5]
    ...     z = f(x,y)
    ...     """)
    ModuleDoc for epydoc_test [0]
     +- canonical_name = DottedName('epydoc_test')
     +- defining_module
     |  +- ModuleDoc for epydoc_test [0] (defined above)
     +- docs_extracted_by = 'parser'
     +- filename = ...
     +- imports = []
     +- is_package = False
     +- package = None
     +- sort_spec = [u'x', u'y', u'z']
     +- submodules = []
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
        |  +- container
        |  |  +- ModuleDoc for epydoc_test [0] (defined above)
        |  +- docs_extracted_by = 'parser'
        |  +- is_alias = False
        |  +- is_imported = False
        |  +- is_instvar = False
        |  +- is_public = True
        |  +- name = u'x'
        |  +- value
        |     +- GenericValueDoc [2]
        |        +- defining_module
        |        |  +- ModuleDoc for epydoc_test [0] (defined above)
        |        +- docs_extracted_by = 'parser'
        |        +- parse_repr = u'12'
        |        +- toktree = [(2, u'12')]
        +- y => VariableDoc for epydoc_test.y [3]
        |  +- container
        |  |  +- ModuleDoc for epydoc_test [0] (defined above)
        |  +- docs_extracted_by = 'parser'
        |  +- is_alias = False
        |  +- is_imported = False
        |  +- is_instvar = False
        |  +- is_public = True
        |  +- name = u'y'
        |  +- value
        |     +- GenericValueDoc [4]
        |        +- defining_module
        |        |  +- ModuleDoc for epydoc_test [0] (defined above)
        |        +- docs_extracted_by = 'parser'
        |        +- parse_repr = u'[1, 2, 3]+ [4, 5]'
        |        +- toktree = ...
        +- z => VariableDoc for epydoc_test.z [5]
           +- container
           |  +- ModuleDoc for epydoc_test [0] (defined above)
           +- docs_extracted_by = 'parser'
           +- is_alias = False
           +- is_imported = False
           +- is_instvar = False
           +- is_public = True
           +- name = u'z'
           +- value
              +- GenericValueDoc [6]
                 +- defining_module
                 |  +- ModuleDoc for epydoc_test [0] (defined above)
                 +- docs_extracted_by = 'parser'
                 +- parse_repr = u'f(x, y)'
                 +- toktree = ...

    In this example, DocParser decides that the assignment to y is creating an alias. The same ValueDoc is shared by both variables.

    >>> runparser(s="""
    ...     x = [1,2]
    ...     y = x
    ...     """,
    ...     attribs='variables is_alias name value parse_repr')
    ModuleDoc for epydoc_test [0]
     +- parse_repr = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
        |  +- is_alias = False
        |  +- name = u'x'
        |  +- value
        |     +- GenericValueDoc [2]
        |        +- parse_repr = u'[1, 2]'
        +- y => VariableDoc for epydoc_test.y [3]
           +- is_alias = True
           +- name = u'y'
           +- value
              +- GenericValueDoc [2] (defined above)

    DocParser can also parse assignments where the left-hand side is a tuple or list; however, it will not extract values.

    >>> runparser(s="""
    ...     a,b = (5,6)
    ...     [a,(b,[c,d],e),(f,g)] = [1,(2,[3,4],5),(6,7)]
    ...     """,
    ...     attribs='variables is_alias name value')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- a => VariableDoc for epydoc_test.a [1]
        |  +- is_alias = False
        |  +- name = u'a'
        |  +- value = <UNKNOWN>
        +- b => VariableDoc for epydoc_test.b [2]
        |  +- is_alias = False
        |  +- name = u'b'
        |  +- value = <UNKNOWN>
        +- c => VariableDoc for epydoc_test.c [3]
        |  +- is_alias = False
        |  +- name = u'c'
        |  +- value = <UNKNOWN>
        +- d => VariableDoc for epydoc_test.d [4]
        |  +- is_alias = False
        |  +- name = u'd'
        |  +- value = <UNKNOWN>
        +- e => VariableDoc for epydoc_test.e [5]
        |  +- is_alias = False
        |  +- name = u'e'
        |  +- value = <UNKNOWN>
        +- f => VariableDoc for epydoc_test.f [6]
        |  +- is_alias = False
        |  +- name = u'f'
        |  +- value = <UNKNOWN>
        +- g => VariableDoc for epydoc_test.g [7]
           +- is_alias = False
           +- name = u'g'
           +- value = <UNKNOWN>

    DocParser can also parse 'multi-assignment' statements, containing more than one assignment. Note that the ValueDoc object is shared; and all but the rightmost variable are marked as aliases. (As a result, the value's canonical name will use the name of the rightmost variable.)

    >>> runparser(s="""
    ...     x = y = z = 0
    ...     """,
    ...     attribs="variables is_alias name value parse_repr")
    ModuleDoc for epydoc_test [0]
     +- parse_repr = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
        |  +- is_alias = True
        |  +- name = u'x'
        |  +- value
        |     +- GenericValueDoc [2]
        |        +- parse_repr = u'0'
        +- y => VariableDoc for epydoc_test.y [3]
        |  +- is_alias = True
        |  +- name = u'y'
        |  +- value
        |     +- GenericValueDoc [2] (defined above)
        +- z => VariableDoc for epydoc_test.z [4]
           +- is_alias = False
           +- name = u'z'
           +- value
              +- GenericValueDoc [2] (defined above)

    If a variable is assigned to twice, then the later assignment overwrites the earlier one:

    >>> runparser(s="""
    ...     x = 22
    ...     x = 33
    ...     """,
    ...     attribs="variables name value parse_repr")
    ModuleDoc for epydoc_test [0]
     +- parse_repr = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- name = u'x'
           +- value
              +- GenericValueDoc [2]
                 +- parse_repr = u'33'

    Some class variable have a special meaning. The __slots__ variable isn't very useful and should be discarded.

    >>> runparser(s="""
    ...     class Foo:
    ...         __slots__ = ['bar']
    ...         def __init__(self):
    ...             self.bar = 0
    ...     """,
    ...     attribs="variables name value")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- Foo => VariableDoc for epydoc_test.Foo [1]
           +- name = u'Foo'
           +- value
              +- ClassDoc for epydoc_test.Foo [2]
                 +- variables
                    +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [3]
                       +- name = u'__init__'
                       +- value
                          +- RoutineDoc for epydoc_test.Foo.__init__ [4]

    Module Control Blocks

    DocParser will look inside certain types of module-level control blocks. By default, DocParser looks inside the following block types:

    • if blocks
    • elif blocks
    • else blocks
    • try blocks
    • except blocks
    • finally blocks

    By default, DocParse does not look inside the following block types:

    • while blocks

    • for blocks

      >>> # DocParser looks inside if/elif/else blocks.
      >>> runparser(s="""
      ...     if condition:
      ...         if_gated = 'x'
      ...     elif condition2:
      ...         elif_gated = 'y'
      ...     elif condition3:
      ...         elif_gated2 = 'x'
      ...     else:
      ...         else_gated = 'z'""",
      ...     attribs="variables name")
      ModuleDoc for epydoc_test [0]
       +- variables
          +- elif_gated => VariableDoc for epydoc_test.elif_gated [1]
          |  +- name = u'elif_gated'
          +- elif_gated2 => VariableDoc for epydoc_test.elif_gated2 [2]
          |  +- name = u'elif_gated2'
          +- else_gated => VariableDoc for epydoc_test.else_gated [3]
          |  +- name = u'else_gated'
          +- if_gated => VariableDoc for epydoc_test.if_gated [4]
             +- name = u'if_gated'
      >>> # DocParser looks inside try/except and try/finally blocks:
      >>> runparser(s="""
      ...     try:
      ...         try:
      ...             try_gated = 'x'
      ...         except Exception1:
      ...             except_gated = 'x'
      ...         except:
      ...             except_gated2 = 'y'
      ...     finally:
      ...         finally_gated = 'z'""",
      ...     attribs="variables name")
      ModuleDoc for epydoc_test [0]
       +- variables
          +- except_gated => VariableDoc for epydoc_test.except_gated [1]
          |  +- name = u'except_gated'
          +- except_gated2 => VariableDoc for epydoc_test.except_gated2 [2]
          |  +- name = u'except_gated2'
          +- finally_gated => VariableDoc for epydoc_test.finally_gated [3]
          |  +- name = u'finally_gated'
          +- try_gated => VariableDoc for epydoc_test.try_gated [4]
             +- name = u'try_gated'
      >>> # By default, DocParser does not look inside for blocks
      >>> runparser(s="""
      ...     for itervar in [5]*3:
      ...         for_gated = 'x'""",
      ...     attribs="variables name")
      ModuleDoc for epydoc_test [0]
       +- variables = {}
      >>> # By default, DocParser does not look inside while blocks
      >>> runparser(s="""
      ...     while condition:
      ...         while_gated = 'x'""",
      ...     attribs="variables name")
      ModuleDoc for epydoc_test [0]
       +- variables = {}

    The set of blocks that DocParser looks inside are controlled by a set of global variables in epydoc.docparser. For example, the following code creates a DocParser that does look inside for blocks and while blocks:

    >>> import epydoc.docparser
    >>> epydoc.docparser.PARSE_FOR_BLOCKS = True
    >>> epydoc.docparser.PARSE_WHILE_BLOCKS = True
    >>> runparser(s="""
    ...     for itervar in [5]*3:
    ...         for_gated = 'x'""",
    ...     attribs="variables name")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- for_gated => VariableDoc for epydoc_test.for_gated [1]
        |  +- name = u'for_gated'
        +- itervar => VariableDoc for epydoc_test.itervar [2]
           +- name = u'itervar'
    >>> runparser(s="""
    ...     while condition:
    ...         while_gated = 'x'""",
    ...     attribs="variables name")
    ModuleDoc for epydoc_test [0]
     +- variables
        +- while_gated => VariableDoc for epydoc_test.while_gated [1]
           +- name = u'while_gated'
    >>> # reset the globals:
    >>> reload(epydoc.docparser) and None

    Note that when DocParser examines a for block, it also creates a VariableDoc for the loop variable (itervar in this case).

    Variable Docstrings

    The DocParser can extract docstrings for variables. These docstrings can come from one of two places: string constants that immediately follow the assignment statement; or comments starting with the special sequence "#:" that occur before the assignment or on the same line as it.

    >>> runparser(s="""
    ...     x = 12
    ...     '''docstring for x.
    ...     (can be multiline)'''""",
    ...     attribs="variables name docstring")
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = u'docstring for x.\n(can be multiline)'
           +- name = u'x'
    >>> runparser(s="""
    ...     x = 12 #: comment docstring for x""",
    ...     attribs="variables name docstring")
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = u'comment docstring for x'
           +- name = u'x'
    >>> runparser(s="""
    ...     #: comment docstring for x.
    ...     #: (can be multiline)
    ...     x = 12""",
    ...     attribs="variables name docstring")
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = u'comment docstring for x.\n(can be m...
           +- name = u'x'

    If comments and a string constant are both used, then the string constant takes precedence:

    >>> runparser(s="""
    ...     #: comment1
    ...     x = 12 #: comment2
    ...     '''string'''""",
    ...     attribs="variables name docstring")
    <UNKNOWN> has both a comment-docstring and a normal (string) docstring; ignoring the comment-docstring.
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- docstring = u'string'
           +- name = u'x'

    Functions

    When DocParser encounters a function definition statement, it creates a corresponding FunctionDoc object (as the valuedoc attribute of a VariableDoc object in the module's children list).

    >>> runparser(s="""
    ...     def f(x):
    ...         'docstring for f'
    ...         print 'inside f'
    ...     """, show="f", exclude='defining_module')
    RoutineDoc for epydoc_test.f [0]
     +- canonical_name = DottedName('epydoc_test', u'f')
     +- decorators = []
     +- docs_extracted_by = 'parser'
     +- docstring = u'docstring for f'
     +- docstring_lineno = 3
     +- kwarg = None
     +- lineno = 2
     +- posarg_defaults = [None]
     +- posargs = [u'x']
     +- vararg = None

    The function's arguments are described by the properties posargs, posarg_defaults, kwarg, and vararg. posargs is a list of argument names (or nested tuples of names, for tuple-unpacking args). posarg_defaults is a list of ValueDocs for default values, corresponding 1:1 with posargs. posarg_defaults is None for arguments with no default value. vararg and kwarg are the names of the variable argument and keyword argument, respectively:

    >>> runparser(s="""
    ...     def f(x, y=22, z=(1,), *v, **kw):
    ...         'docstring for f'
    ...         print 'inside f'
    ...     """, show="f", exclude='defining_module')
    RoutineDoc for epydoc_test.f [0]
     +- canonical_name = DottedName('epydoc_test', u'f')
     +- decorators = []
     +- docs_extracted_by = 'parser'
     +- docstring = u'docstring for f'
     +- docstring_lineno = 3
     +- kwarg = u'kw'
     +- lineno = 2
     +- posarg_defaults = [None, <GenericValueDoc None>, <Gener...
     +- posargs = [u'x', u'y', u'z']
     +- vararg = u'v'
    Tuple arguments are encoded as a single ArgDoc with a complex name:
    >>> runparser(s="""
    ...     def f( (x, (y,z)) ): pass
    ...     """, show="f", exclude='defining_module')
    RoutineDoc for epydoc_test.f [0]
     +- canonical_name = DottedName('epydoc_test', u'f')
     +- decorators = []
     +- docs_extracted_by = 'parser'
     +- kwarg = None
     +- lineno = 2
     +- posarg_defaults = [None]
     +- posargs = [[u'x', [u'y', u'z']]]
     +- vararg = None

    Decorators & Wrapper Assignments

    >>> runparser( # doctest: +PYTHON2.4
    ...     s="""
    ...     @classmethod
    ...     def f(cls, x): 'docstring for f'
    ...     """,
    ...     attribs='variables value docstring posargs')
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- f => VariableDoc for epydoc_test.f [1]
           +- docstring = <UNKNOWN>
           +- value
              +- ClassMethodDoc for epydoc_test.f [2]
                 +- docstring = u'docstring for f'
                 +- posargs = [u'cls', u'x']

    Classes

    >>> runparser(s="""
    ...     class A:
    ...         "no bases"
    ...         class Nested: "nested class"
    ...     class B(A): "single base"
    ...     class C(A,B): "multiple bases"
    ...     class D( ((A)) ): "extra parens around base"
    ...     class E(A.Nested): "dotted name"
    ...     class F(((A).Nested)): "parens with dotted name"
    ...     class Z(B.__bases__[0]): "calculated base" # not handled!
    ...     """,
    ...     attribs='variables value bases docstring')
    Unable to extract the base list for epydoc_test.Z: Bad dotted name
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.A [2]
        |        +- bases = []
        |        +- docstring = u'no bases'
        |        +- variables
        |           +- Nested => VariableDoc for epydoc_test.A.Nested [3]
        |              +- docstring = <UNKNOWN>
        |              +- value
        |                 +- ClassDoc for epydoc_test.A.Nested [4]
        |                    +- bases = []
        |                    +- docstring = u'nested class'
        |                    +- variables = {}
        +- B => VariableDoc for epydoc_test.B [5]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.B [6]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        +- docstring = u'single base'
        |        +- variables = {}
        +- C => VariableDoc for epydoc_test.C [7]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.C [8]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        |  +- ClassDoc for epydoc_test.B [6] (defined above)
        |        +- docstring = u'multiple bases'
        |        +- variables = {}
        +- D => VariableDoc for epydoc_test.D [9]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.D [10]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A [2] (defined above)
        |        +- docstring = u'extra parens around base'
        |        +- variables = {}
        +- E => VariableDoc for epydoc_test.E [11]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.E [12]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A.Nested [4] (defined above)
        |        +- docstring = u'dotted name'
        |        +- variables = {}
        +- F => VariableDoc for epydoc_test.F [13]
        |  +- docstring = <UNKNOWN>
        |  +- value
        |     +- ClassDoc for epydoc_test.F [14]
        |        +- bases
        |        |  +- ClassDoc for epydoc_test.A.Nested [4] (defined above)
        |        +- docstring = u'parens with dotted name'
        |        +- variables = {}
        +- Z => VariableDoc for epydoc_test.Z [15]
           +- docstring = <UNKNOWN>
           +- value
              +- ClassDoc for epydoc_test.Z [16]
                 +- bases = <UNKNOWN>
                 +- docstring = u'calculated base'
                 +- variables = {}

    Base lists:

    Delete Statements

    Deleting variables:

    >>> runparser(s="""
    ...     x = y = 12
    ...     del y
    ...     """,
    ...     attribs='variables value parse_repr is_alias')
    ModuleDoc for epydoc_test [0]
     +- parse_repr = <UNKNOWN>
     +- variables
        +- x => VariableDoc for epydoc_test.x [1]
           +- is_alias = True
           +- value
              +- GenericValueDoc [2]
                 +- parse_repr = u'12'

    The right-hand side of a del statement may contain a nested combination of lists, tuples, and parenthases. All variables found anywhere in this nested structure should be deleted:

    >>> runparser(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del a
    ...     del (b)
    ...     del [c]
    ...     del (d,)
    ...     del (((e,)),)
    ...     del [[[[f]]]]
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]
    >>> runparser(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del a,b
    ...     del (c,d)
    ...     del [e,f]
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]
    >>> runparser(s="""
    ...     a=b=c=d=e=f=g=1
    ...     del ((a, (((((b, c)), d), [e]))), f)
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- g => VariableDoc for epydoc_test.g [1]

    The right-hand side of a del statement may contain a dotted name, in which case the named variable should be deleted from its containing namespace.

    >>> runparser(s="""
    ...     class A: a = b = 1
    ...     del A.a
    ...     """,
    ...     attribs='variables value local_variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- variables
                    +- b => VariableDoc for epydoc_test.A.b [3]
                       +- value
                          +- GenericValueDoc [4]

    If one of the variables to be deleted is expressed as anything other than a simple identifier or a dotted name, then ignore it. (In particular, if we encounter 'del x[2]' then do not delete x.)

    >>> runparser(s="""
    ...     a = b = [1,2,3,4]
    ...     del a[2]
    ...     del a[2:]
    ...     del ([b], a[1])
    ...     """,
    ...     attribs='variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- a => VariableDoc for epydoc_test.a [1]

    Single-Line Blocks

    >>> runparser(s="""
    ...     class A: 'docstring for A'
    ...
    ...
    ...     """,
    ...     attribs='variables value docstring')
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- docstring = <UNKNOWN>
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- docstring = u'docstring for A'
                 +- variables = {}

    Imports

    >>> runparser(s="""
    ...     import re
    ...     from re import match
    ...     """,
    ...     attribs='variables value is_imported')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- match => VariableDoc for epydoc_test.match [1]
        |  +- is_imported = True
        |  +- value = <UNKNOWN>
        +- re => VariableDoc for epydoc_test.re [2]
           +- is_imported = True
           +- value = <UNKNOWN>
    >>> runparser(s="""
    ...     from re import match as much, split, sub as scuba
    ...     """,
    ...     attribs='variables name imported_from')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- much => VariableDoc for epydoc_test.much [1]
        |  +- imported_from = DottedName(u're', u'match')
        |  +- name = u'much'
        +- scuba => VariableDoc for epydoc_test.scuba [2]
        |  +- imported_from = DottedName(u're', u'sub')
        |  +- name = u'scuba'
        +- split => VariableDoc for epydoc_test.split [3]
           +- imported_from = DottedName(u're', u'split')
           +- name = u'split'

    Unicode

    >>> runparser(s="""
    ...     def f(x):
    ...         u"unicode in docstring: \u1000"
    ...     """,
    ...     attribs='variables value docstring')
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- f => VariableDoc for epydoc_test.f [1]
           +- docstring = <UNKNOWN>
           +- value
              +- RoutineDoc for epydoc_test.f [2]
                 +- docstring = u'unicode in docstring: \u1000'

    Instance Variables

    >>> runparser(s="""
    ...     class A:
    ...         def __init__(self, x, y):
    ...             self.x = 10
    ...
    ...             self.y = 20 #: docstring for y
    ...
    ...             self.z = 30
    ...             '''docstring for z'''
    ...
    ...     """,
    ...     attribs='variables value is_instvar docstring local_variables')
    ModuleDoc for epydoc_test [0]
     +- docstring = <UNKNOWN>
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- docstring = <UNKNOWN>
           +- is_instvar = <UNKNOWN>
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- docstring = <UNKNOWN>
                 +- variables
                    +- __init__ => VariableDoc for epydoc_test.A.__init__ [3]
                    |  +- docstring = <UNKNOWN>
                    |  +- is_instvar = <UNKNOWN>
                    |  +- value
                    |     +- RoutineDoc for epydoc_test.A.__init__ [4]
                    |        +- docstring = <UNKNOWN>
                    +- y => VariableDoc for epydoc_test.A.y [5]
                    |  +- docstring = u'docstring for y'
                    |  +- is_instvar = True
                    |  +- value = <UNKNOWN>
                    +- z => VariableDoc for epydoc_test.A.z [6]
                       +- docstring = u'docstring for z'
                       +- is_instvar = True
                       +- value = <UNKNOWN>

    Assignments Into Namespaces

    >>> runparser(s="""
    ...     class A: pass
    ...     A.x = 22
    ...     """,
    ...     attribs='variables value local_variables')
    ModuleDoc for epydoc_test [0]
     +- variables
        +- A => VariableDoc for epydoc_test.A [1]
           +- value
              +- ClassDoc for epydoc_test.A [2]
                 +- variables
                    +- x => VariableDoc for epydoc_test.A.x [3]
                       +- value
                          +- GenericValueDoc [4]
    >>> runparser(s="""
    ...     Exception.x = 10
    ...     """,
    ...     attribs='variables value local_variables')
    ModuleDoc for epydoc_test [0]
     +- variables = {}
    epydoc-3.0.1+dfsg/doc/doctest/restructuredtext.html0000644000175000017500000004443510750103051022737 0ustar pronovicpronovic Regression Testing for restructuredtext

    Regression Testing for restructuredtext

    RequireModule:

    docutils

    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Summary

    The implementation of the summaization function works as expected.

    >>> from epydoc.markup import restructuredtext
    >>> def getsummary(s):
    ...     p = restructuredtext.parse_docstring(s, [])
    ...     s, o = p.summary()
    ...     s = s.to_plaintext(None).strip()
    ...     return s, o

    #Let's not lose anything!

    >>> getsummary("Single line")
    (u'Single line', False)
    >>> getsummary("Single line.")
    (u'Single line.', False)
    >>> getsummary("""
    ... Single line *with* period.
    ... """)
    (u'Single line with period.', False)
    >>> getsummary("""
    ... Single line `with` period.
    ...
    ... :type: Also with a tag.
    ... """)
    (u'Single line with period.', False)
    >>> getsummary("""
    ... Other lines **with** period.
    ... This is attached
    ... """)
    (u'Other lines with period.', True)
    >>> getsummary("""
    ... Other lines *with* period.
    ...
    ... This is detached
    ...
    ... :type: Also with a tag.
    ... """)
    (u'Other lines with period.', True)
    >>> getsummary("""
    ... Other lines without period
    ... This is attached
    ... """)
    (u'Other lines without period\nThis is attached', False)
    >>> getsummary("""
    ... Other lines without period
    ...
    ... This is detached
    ... """)
    (u'Other lines without period...', True)
    >>> getsummary("""
    ... Single line *without* period
    ...
    ... :type: Also with a tag.
    ... """)
    (u'Single line without period', False)
    >>> getsummary("""
    ... This is the first line.
    ...
    ... :type: Also with a tag.
    ...
    ... Other stuff after a tag.
    ... """)
    (u'This is the first line.', True)

    Python code

    reStructuredText markup defines a python directive to represent a block as colorized Python code.

    >>> err = []
    >>> p = restructuredtext.parse_docstring(
    ... """A test module
    ...
    ... .. python::
    ...
    ...     # This is some Python code
    ...     def foo():
    ...         pass
    ...
    ...     class Foo:
    ...         def __init__(self):
    ...             pass
    ... """, err)
    >>> err
    []
    >>> print p.to_html(None)
    <p>A test module</p>
    <pre class="py-doctest">
    <span class="py-comment"># This is some Python code</span>
    <span class="py-keyword">def</span> <span class="py-defname">foo</span>():
        <span class="py-keyword">pass</span>
    <BLANKLINE>
    <span class="py-keyword">class</span> <span class="py-defname">Foo</span>:
        <span class="py-keyword">def</span> <span class="py-defname">__init__</span>(self):
            <span class="py-keyword">pass</span></pre>
    <BLANKLINE>

    Consolidated Fields

    >>> from epydoc.test.util import runbuilder
    >>> runbuilder(s='''
    ...     __docformat__ = 'restructuredtext'
    ...     class Foo:
    ...         """This is the object docstring
    ...
    ...         :Parameters:
    ...           `a` : string
    ...             init param.
    ...
    ...         :Exceptions:
    ...           * `ValueError`: frobnication error
    ...             init param.
    ...
    ...         :IVariables:
    ...           `a` : date
    ...             instance var.
    ...         """
    ...         def __init__(self, a):
    ...             pass
    ...     ''',
    ...     build="Foo",
    ...     attribs="variables name value exception_descrs "
    ...         "posargs vararg kwarg type_descr arg_types arg_descrs")
    ClassDoc for epydoc_test.Foo [0]
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
        |  +- name = '__init__'
        |  +- type_descr = None
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.__init__ [2]
        |        +- arg_descrs = [([u'a'], u'init param.')]
        |        +- arg_types = {u'a': u'string'}
        |        +- exception_descrs = [(DottedName(u'ValueError'), ...
        |        +- kwarg = None
        |        +- posargs = ['self', 'a']
        |        +- vararg = None
        +- a => VariableDoc for epydoc_test.Foo.a [3]
           +- name = u'a'
           +- type_descr = u'date'
           +- value = <UNKNOWN>

    Misc rst constructs

    >>> runbuilder(s='''
    ...     __docformat__ = 'restructuredtext'
    ...
    ...     class Foo:
    ...         """Testing defining_module
    ...
    ...         :cvar `c`: class var in class docstring
    ...         :type `c`: str
    ...         """
    ...         c = 'abc'
    ...
    ...         def __init__(self):
    ...             #: A funny number
    ...             #:
    ...             #: :type: float
    ...             self.x = 108.0
    ...
    ...         y = property(
    ...             fget=lambda self: 42,
    ...             doc="""A property has no defining module
    ...
    ...             :type: int
    ...             """)
    ...
    ...         def f(self):
    ...             """A function has a defining module
    ...
    ...             :rtype: int
    ...             """
    ...             return 42
    ...     ''',
    ...     build='Foo',
    ...     attribs="variables name value type_descr return_type descr")
    ClassDoc for epydoc_test.Foo [0]
     +- descr = u'Testing defining_module'
     +- variables
        +- __init__ => VariableDoc for epydoc_test.Foo.__init__ [1]
        |  +- descr = None
        |  +- name = '__init__'
        |  +- type_descr = None
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.__init__ [2]
        |        +- descr = None
        |        +- return_type = None
        +- c => VariableDoc for epydoc_test.Foo.c [3]
        |  +- descr = u'class var in class docstring'
        |  +- name = 'c'
        |  +- type_descr = u'str'
        |  +- value
        |     +- GenericValueDoc [4]
        |        +- descr = None
        +- f => VariableDoc for epydoc_test.Foo.f [5]
        |  +- descr = None
        |  +- name = 'f'
        |  +- type_descr = None
        |  +- value
        |     +- RoutineDoc for epydoc_test.Foo.f [6]
        |        +- descr = u'A function has a defining module'
        |        +- return_type = u'int'
        +- x => VariableDoc for epydoc_test.Foo.x [7]
        |  +- descr = u'A funny number'
        |  +- name = u'x'
        |  +- type_descr = u'float'
        |  +- value = <UNKNOWN>
        +- y => VariableDoc for epydoc_test.Foo.y [8]
           +- descr = None
           +- name = 'y'
           +- type_descr = None
           +- value
              +- PropertyDoc for epydoc_test.Foo.y [9]
                 +- descr = u'A property has no defining module'
                 +- type_descr = u'int'
    epydoc-3.0.1+dfsg/doc/doctest/zope2.html0000644000175000017500000001305610750103051020331 0ustar pronovicpronovic Regression Testing for Zope 2 support

    Regression Testing for Zope 2 support

    RequireModule:

    ExtensionClass

    >>> from epydoc.test.util import runintrospecter

    We treat extension classes as if they were classes:

    >>> from ExtensionClass import ExtensionClass
    >>> runintrospecter(s='''
    ...     from ExtensionClass import ExtensionClass
    ...     ''', attribs='variables value pyval',
    ...     introspect='ExtensionClass')
    ClassDoc [0]
     +- pyval = <extension class ExtensionClass at 40...
     +- variables
        +- __basicnew__ => VariableDoc for __basicnew__ [1]
        |  +- value
        |     +- RoutineDoc [2]
        |        +- pyval = <CMethod object at ...>
        +- __call__ => VariableDoc for __call__ [3]
        |  +- value
        |     +- RoutineDoc [4]
        |        +- pyval = <CMethod object at ...>
        +- __delattr__ => VariableDoc for __delattr__ [5]
        |  +- value
        |     +- RoutineDoc [6]
        |        +- pyval = <CMethod object at ...>
        +- __getattr__ => VariableDoc for __getattr__ [7]
        |  +- value
        |     +- RoutineDoc [8]
        |        +- pyval = <CMethod object at ...>
        +- __init__ => VariableDoc for __init__ [9]
        |  +- value
        |     +- RoutineDoc [10]
        |        +- pyval = <CMethod object at ...>
        +- __reduce__ => VariableDoc for __reduce__ [11]
        |  +- value
        |     +- RoutineDoc [12]
        |        +- pyval = <CMethod object at ...>
        +- __repr__ => VariableDoc for __repr__ [13]
        |  +- value
        |     +- RoutineDoc [14]
        |        +- pyval = <CMethod object at ...>
        +- __setattr__ => VariableDoc for __setattr__ [15]
        |  +- value
        |     +- RoutineDoc [16]
        |        +- pyval = <CMethod object at ...>
        +- inheritedAttribute => VariableDoc for inheritedAttribute [17]
           +- value
              +- RoutineDoc [18]
                 +- pyval = <CMethod object at ...>

    (If we didn't add special support, ExtensionClass would be a GenericValueDoc.)

    epydoc-3.0.1+dfsg/doc/doctest/javadoc.html0000644000175000017500000001464610750103051020707 0ustar pronovicpronovic Regression Testing for javadoc

    Regression Testing for javadoc

    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Summary

    The implementation of the summaization function works as expected.

    >>> from epydoc.markup import javadoc
    >>> def getsummary(s):
    ...     p = javadoc.parse_docstring(s, [])
    ...     s, o = p.summary()
    ...     s = s.to_plaintext(None).strip()
    ...     return s, o

    #Let's not lose anything!

    >>> getsummary("Single line")
    ('Single line', False)
    >>> getsummary("Single line.")
    ('Single line.', False)
    >>> getsummary("""
    ... Single line <i>with</i> period.
    ... """)
    ('Single line <i>with</i> period.', False)
    >>> getsummary("""
    ... Single line <i>with</i> period.
    ...
    ... @type Also with a tag.
    ... """)
    ('Single line <i>with</i> period.', False)
    >>> getsummary("""
    ... Other lines <i>with</i> period.
    ... This is attached
    ... """)
    ('Other lines <i>with</i> period.', True)
    >>> getsummary("""
    ... Other lines <i>with</i> period.
    ...
    ... This is detached
    ...
    ... @type Also with a tag.
    ... """)
    ('Other lines <i>with</i> period.', True)
    >>> getsummary("""
    ... Other lines without period
    ... This is attached
    ... """)
    ('Other lines without period...', True)
    >>> getsummary("""
    ... Other lines without period
    ...
    ... This is detached
    ... """)
    ('Other lines without period...', True)
    >>> getsummary("""
    ... Single line <i>without</i> period
    ...
    ... @type Also with a tag.
    ... """)
    ('Single line <i>without</i> period', False)
    epydoc-3.0.1+dfsg/doc/doctest/apidoc.html0000644000175000017500000004421310750103050020527 0ustar pronovicpronovic Regression Testing for epydoc.apidoc

    Regression Testing for epydoc.apidoc

    This file serves to provide both documentation and regression tests for the epydoc.apidoc module. The main purpose of this module is to define the APIDoc class hierarchy, which is used to encode API documentation about Python programs. The API documentation for a Python program is encoded using a graph of APIDoc objects, each of which encodes information about a single Python variable or value.

    >>> import epydoc; epydoc.DEBUG = True
    >>> from epydoc.apidoc import *
    >>> from epydoc.test.util import print_warnings
    >>> print_warnings()

    Unknown Value

    Epydoc defines a special object, epydoc.apidoc.UNKNOWN, which is used as the value of attributes when their real value is not (yet) known.

    >>> UNKNOWN
    <UNKNOWN>

    This object only compares equal to itself:

    >>> UNKNOWN == False
    False
    >>> UNKNOWN == True
    False
    >>> UNKNOWN == 'UNKNOWN'
    False
    >>> UNKNOWN == 0
    False
    >>> UNKNOWN == []
    False
    >>> UNKNOWN == object()
    False
    >>> UNKNOWN == UNKNOWN
    True

    If UNKNOWN is used in a context where it is cast to bool, then it will raise an exception. This helps prevent acidentally interpreting an UNKNOWN value as true or false:

    >>> if UNKNOWN:
    ...     print 'ok'
    Traceback (most recent call last):
    ValueError: Sentinel value <UNKNOWN> can not be used as a boolean

    To test an attribute whose value might be UNKNOWN, you should explicitly compare that value to True or False. E.g.:

    >>> x = UNKNOWN
    >>> if x is True:
    ...     print 'we know x is true, and not unknown'
    >>> if x is not False:
    ...     print 'x might be true or unknown.'
    x might be true or unknown.
    >>> if x in (True, UNKNOWN):
    ...     print 'x might be true or unknown.'
    x might be true or unknown.

    Dotted Names

    The DottedName class is used to encode dotted names, such as 'epydoc.apidoc.DottedName', and make them easier to work with. Conceptually, a dotted name consists of a sequence of identifiers, separated by periods.

    Dotted names can be constructed from strings:

    >>> name1 = DottedName('foo.bar')
    >>> name1
    DottedName('foo', 'bar')

    Note that the given name is split on periods. You may also pass multiple strings to the constructor; they will be combined together into a single sequence:

    >>> name2 = DottedName('x.y', 'z')
    >>> name2
    DottedName('x', 'y', 'z')

    Each string can be a single identifier or a sequence of identifiers joined py periods. You may also pass DottedName objects to the constructor; their sequence of identifiers will be used:

    >>> name3 = DottedName(name1, name2)
    >>> name3
    DottedName('foo', 'bar', 'x', 'y', 'z')

    The string representation of a dotted name is formed by joining the identifiers with periods:

    >>> str(name1)
    'foo.bar'
    >>> str(name2)
    'x.y.z'
    >>> str(name3)
    'foo.bar.x.y.z'

    The individual identifiers of a dotted name can be accessed via indexing; and the number of identifiers is returned by the len operator:

    >>> name1[0], name1[1]
    ('foo', 'bar')
    >>> name3[-1]
    'z'
    >>> name3[1:3]
    DottedName('bar', 'x')
    >>> len(name2)
    3

    As a result, you can iterate over the identifiers in a dotted name:

    >>> for ident in name1:
    ...     print ident
    foo
    bar

    Two dotted names compare equal if they have the same number of identifies and they are pairwise equal:

    >>> DottedName('foo.bar') == DottedName('foo', 'bar')
    True
    >>> DottedName('foo.bar') == DottedName('foo.baz')
    False
    >>> DottedName('foo.bar') == DottedName('foo.bar.baz')
    False

    Dotted names may be combined with the addition operator:

    >>> name1 + name2
    DottedName('foo', 'bar', 'x', 'y', 'z')
    >>> name1 + name2 == name3
    True
    >>> name2 + name1 == name3
    False

    The container method may be used to construct a new dotted name with the last identifier stripped off:

    >>> name1.container()
    DottedName('foo')
    >>> name3.container()
    DottedName('foo', 'bar', 'x', 'y')

    If a dotted name has only one identifier, then its container is None:

    >>> print DottedName('baz').container()
    None
    >>> print name1.container().container()
    None

    It is an error to create an empty dotted name; or a dotted name that contains a string that's not a valid python identifier:

    >>> DottedName()
    Traceback (most recent call last):
    InvalidDottedName: Empty DottedName
    >>> DottedName('1+2', strict=True)
    Traceback (most recent call last):
    InvalidDottedName: Bad identifier '1+2'
    >>> DottedName({})
    Traceback (most recent call last):
    TypeError: Bad identifier {}: expected DottedName or str
    >>> DottedName('1+2', strict=False)
    Identifier '1+2' looks suspicious; using it anyway.
    DottedName('1+2')

    The one exception is that '??' is treated as if it were a valid python identifier:

    >>> DottedName('??', 'foo')
    DottedName('??', 'foo')

    This is used when we can't find any name for an object (e.g., if there's a class that was used as the base class, but is not contained in any module or class).

    A dotted name can be queried into a context to obtain a reduced version:

    >>> DottedName('foo.bar').contextualize(DottedName('foo'))
    DottedName('bar')
    >>> DottedName('foo.bar.baz.qux').contextualize(DottedName('foo.bar'))
    DottedName('baz', 'qux')
    >>> DottedName('foo.bar').contextualize(DottedName('baz'))
    DottedName('foo', 'bar')
    >>> DottedName('foo.bar').contextualize(DottedName('foo').container())
    DottedName('foo', 'bar')
    >>> DottedName('foo.bar').contextualize(UNKNOWN)
    DottedName('foo', 'bar')

    But a contextualization can't reduce to an empty DottedName:

    >>> DottedName('foo').contextualize(DottedName('foo'))
    DottedName('foo')

    APIDoc Objects

    API documentation about Python programs is broken into small pieces, each of which is encoded using a single APIDoc object. Each APIDoc object describes a single value, variable, or function argument.

    The APIDoc base class has 2 direct subclasses, for the 2 basic types of entity that it can record information about: ValueDoc and VariableDoc. ValueDoc is further subclassed to specify the different pieces of information that should be recorded about each value type.

    APIDoc objects record information about each entity using attributes. Attribute values may be specified in the constructor. Any attributes that are not specified will be given a default value (usually UNKNOWN). The APIDoc base class defines the attributes shared by all APIDoc objects: docstring, docstring_lineno, descr, summary, metadata, and extra_docstring_fields.

    >>> api_doc = APIDoc(docstring='foo')
    >>> api_doc.docstring
    'foo'
    >>> api_doc.summary
    <UNKNOWN>

    The constructor does not accept positional arguments; and any keyword argument that does not correspond to a valid attribute will generate a TypeError (but only if epydoc.DEBUG is true):

    >>> APIDoc('foo')
    Traceback (most recent call last):
    TypeError: __init__() takes exactly 1 argument (2 given)
    >>> APIDoc(foo='foo')
    Traceback (most recent call last):
    TypeError: APIDoc got unexpected arg 'foo'

    Any assignment to an attribute that's not valid will also generate a TypeError (but only if epydoc.DEBUG is true):

    >>> api_doc = APIDoc(docstring='ds')
    >>> api_doc.foo = 0
    Traceback (most recent call last):
    AttributeError: APIDoc does not define attribute 'foo'

    APIDoc defines a pretty-print method, pp(), which can be used to display the information that an APIDoc contains:

    >>> val_doc = ValueDoc(pyval=3)
    >>> var_doc = VariableDoc(name='x', value=val_doc)
    >>> class_doc = ClassDoc(bases=(), variables={'x':var_doc})
    >>> print class_doc.pp()
    ClassDoc [0]
     +- bases = ()
     +- variables
        +- x => VariableDoc for x [1]
           +- is_public = True
           +- name = 'x'
           +- value
              +- ValueDoc [2]
                 +- pyval = 3

    This is mainly intended to be used as a debugging and testing tool. The attributes that will be pretty-printed for an APIDoc object are determined by its class's _STR_FIELDS variable. (But any attribute whose value is UNKNOWN will not be displayed.) Attributes are listed in alphabetical order.

    epydoc-3.0.1+dfsg/man/0002755000175000017500000000000010750103105014742 5ustar pronovicpronovicepydoc-3.0.1+dfsg/man/epydocgui.10000644000175000017500000003260310654406442017033 0ustar pronovicpronovic.\" .\" Epydoc graphical interface man page. .\" $Id: epydocgui.1 405 2002-11-07 10:52:37Z edloper $ .\" .TH EPYDOCGUI 1 .SH NAME epydocgui \- graphical interface to epydoc .\" ================== SYNOPSIS ==================== .SH SYNOPSIS .PP .B epydocgui .RI [ project.prj " | " modules ...] .PP .B epydoc \-h .PP .B epydoc \-V .\" ================== DESCRIPTION ==================== .SH DESCRIPTION .B epydocgui is a graphical interface to epydoc, which generates API documentation for Python modules and packages, based on their docstrings. A lightweight markup language called .B epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. .PP The API documentation produced by .B epydocgui consists of a set of HTML files. Two subdirectories are created for the public and private documentation. Within each subdirectories, every class and module is documented in its own file. An index file, a trees file, and a help file are also created. If you select the .B frames option, then a frames\-based table of contents is also produced. .\" ================== OPTIONS ==================== .SH OPTIONS .TP .I project.prj The name of a project file that was saved with .BR epydocgui . Project files record a list of related modules, and the options that should be used to generate the documentation for those modules. .TP .IR modules ... The list of the modules that should be documented. Modules can be specified using module names (such as .BR os.path ), filenames (such as .BR epydoc/epytext.py ), or directory names (such as .BR epydoc/ ). Directory names specify packages, and are expanded to include all sub-modules and sub-packages. .TP .B \-h, \-\-help, \-\-usage, \-? Display a usage message. .TP .B \-V, \-\-version Print the version of Epydoc. .\" ================== HTML FILES ==================== .\" (this was copied from epydoc.1) .SH HTML FILES The API documentation produced by .B epydoc consists of the following files: .RS 4 .TP .B index.html The standard entry point for the documentation. Normally, .B index.html is a frame index file, which defines three frames: two frames on the left side of the browser contain a table of contents, and the main frame on the right side of the window contains documentation pages. But if the .B \-\-no\-frames option is used, then .B index.html will redirect the user to the project's top page. .TP .BI m- module .html The API documentation for a module. .I module is the complete dotted name of the module, such as .B sys or .BR epydoc.epytext . .TP .BI c- class .html The API documentation for a class, exception, or type. .I class is the complete dotted name of the class, such as .B epydoc.epytext.Token or .BR array.ArrayType . .TP .B trees.html The module and class hierarchies. .TP .B indices.html The term and identifier indices. .TP .B help.html The help page for the project. This page explains how to use and navigate the webpage produced by epydoc. .TP .B toc.html The top\-level table of contents page. This page is displayed in the upper\-left frame, and provides links to .B toc\-everything.html and the .BI toc\-m\- module .html files. .B toc.html is not generated if the .B \-\-no\-frames option is used. .TP .B toc\-everything.html The table of contents for the entire project. This page is displayed in the lower\-left frame, and provides links to every class, type, exception, function, and variable defined by the project. .B toc\-everything.html is not generated if the .B \-\-no\-frames option is used. .TP .BI toc\-m\- module .html The table of contents for a module. This page is displayed in the lower\-left frame, and provides links to every class, type, exception, function, and variable defined by the module. .I module is the complete dotted name of the module, such as .B sys or .BR epydoc.epytext . .BI toc\-m\- module .html is not generated if the .B \-\-no\-frames option is used. .TP .B epydoc.css The CSS stylesheet used to display all HTML pages. .RE .PP By default, .B epydoc creates two subdirectories in the output directory: .B public and .BR private . Each directory contains all of the files specified above. But if the .B \-\-no\-private option is used, then no subdirectories are created, and the public documentation is written directly to the output directory. .\" ================== DIAGNOSTICS ==================== .\" (this was copied from epydoc.1) ivided into five categories: import errors; epytext errors; epytext warnings; field warnings; and inspection errors. Whenver epydoc encounters an error, it issues a warning message that describes the error, and attempts to continue generating documentation. .PP Import errors indicate that epydoc was unable to import a module. Import errors typically prevent epydoc from generating documentation for the module in question. Epydoc can generate the following import errors: .RS 4 .TP .BI "Bad module name " module Epydoc attempted to import .IR module , but .I module is not a valid name for a Python module. .TP .BI "Could not find a UID for " link-target Epydoc was unable to find the object referred to by an inline link construction .RB ( "L{...}" ). This is usually caused by a typo in the link. .TP .BI "Could not import " module Epydoc attempted to import .IR module , but it failed. This typically occurs when .I module raises an exception. .TP .IB file " does not exist" Epydoc attempted to import the module contained in .IR file , but .I file does not exist. .RE .PP Epytext errors are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring. Epydoc can generate the following epytext errors: .RS 4 .TP .B Bad link target. The target specified for an inline link contruction .RB ( "L{...}" ) is not well-formed. Link targets must be valid python identifiers. .TP .B Bad uri target. The target specified for an inline uri contruction .RB ( "U{...}" ) is not well-formed. This typically occurs if inline markup is nested inside the URI target. .TP .B Fields must be at the top level. The list of fields .RB "(" @param ", etc.)" is contained by some other block structure (such as a list or a section). .TP .B Fields must be the final elements. The list of fields .RB "(" @param ", etc.)" is not at the end of a docstring. .TP .B Headings must occur at top level. The heading is contianed in some other block structure (such as a list). .TP .B Improper doctest block indentation. The doctest block dedents past the indentation of its initial prompt line. .TP .B Improper heading indentation. The heading for a section is not left-aligned with the paragraphs in the section that contains it. .TP .B Improper paragraph indentation. The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext. .TP .B Invalid escape. An unknown escape sequence was used with the inline escape construction .RB ( "E{...}" ). .TP .B Lists must be indented. An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet. .TP .B Unbalanced '{'. The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace). .TP .B Unbalanced '}'. The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace). .TP .B Unknown inline markup tag. An unknown tag was used with the inline markup construction ( .IB x {...} ). .TP .B Wrong underline character for heading. The underline character used for this section heading does not indicate an appopriate section level. The "=" character should be used to underline sections; "-" for subsections; and "~" for subsubsections. .RE .PP Epytext warnings are caused by epytext docstrings that contain questionable or suspicious markup. Epytext warnings do .B not prevent the docstring in question from being parsed. Epydoc can generate the following epytext warnings: .RS 4 .TP .B Possible mal-formatted field item. Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (":") is not included in the field tag. .TP .B Possible heading typo. Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading. .RE .PP Field warnings are caused by epytext docstrings containing invalid fields. The contents of the invalid field are generally ignored. Epydoc can generate the following field warnings: .RS 4 .TP .BI "@param for unknown parameter " param . A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name. .TP .IB tag " did not expect an argument." The field tag .I tag was used with an argument, but it does not take one. .TP .IB tag " expected an argument." The field tag .I tag was used without an argument, but it requires one. .TP .BI "@type for unknown parameter " param . A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name. .TP .BI "@type for unknown variable " var . A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name. .TP .BI "Unknown field tag " tag . A docstring contains a field with the unknown tag .IR tag . .TP .BI "Redefinition of " field . Multiple field tags define the value of .I field in the same docstring, but .I field can only take a single value. .RE .PP Inspection errors are generated if epydoc encounters problems while attempting to inspect the properties of a documented object. Most of inspection errors do not prevent epydoc from documenting the object in question. Epydoc can generate the following inspection errors: .RS 4 .TP .BI "The parameters of " inhmethod " do not match " basemethod . The parameters of the undocumented method .I inhmethod do not match the parameters of the base class method .I basemethod that it overrides. As a result, .I inhmethod does not inherit documentation from .IR basemethod . If the difference in parameters is intentional, then you can eliminate the warning by adding a (possibly empty) docstring to .IR inhmethod . .TP .BI "Docmap cannot add a " type Epydoc attempted to document an object with an unknown type. This error is typically generated by packages and modules that manipulate the import mechanism, such that importing a module produces some other type of object. .TP .BI "UID conflict detected: " uid Two different objects were assigned the same unique identifier by epydoc. This can cause epydoc to substitute the documentation of one object with the documentation of another object that is assigned the same unique identifier. However, this will usually only cause problems if the two objects with the same unique identifiers are both modules or classes, in which case the API documentation page for one object will overwrite the API documentation page for the other object. .TP .IB object " appears in multiple builtin modules" While attempting to determine which module defines the builtin object .IR object , epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds. .TP .IB object " appears in multiple .py modules" While attempting to determine which module defines the builtin object .IR object , epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds. .TP .IB object " appears in multiple .so modules" While attempting to determine which module defines the builtin object .IR object , epydoc encountered multiple candidates, and was unable to decide which candidate was correct. In this case, epydoc arbitrarily chooses the first candidate that it finds. .TP .BI "Could not find a module for " object Epydoc was unable to determine which module defines .IR object . If .I object is a function, then this will prevent epydoc from generating any documentation for .IR object , since it does not know what page to put the documentation on. Otherwise, this will prevent the documentation for .I object from including a link to its containing module. .RE .\" ================== AUTHOR ==================== .SH AUTHOR Epydoc was written by Edward Loper. This man page was originally written by Moshe Zadka, and is currently maintained by Edward Loper. .\" ================== BUGS ==================== .SH BUGS Report bugs to . .\" ================== SEE ALSO ==================== .SH SEE ALSO .BR epydoc (1) .TP .B The epydoc webpage .TP .B The epytext markup language manual epydoc-3.0.1+dfsg/man/epydoc.10000644000175000017500000005417510654406442016336 0ustar pronovicpronovic.\" .\" Epydoc command line interface man page. .\" $Id: epydoc.1 1597 2007-07-25 04:59:18Z edloper $ .\" .TH EPYDOC 1 .SH NAME epydoc \- generate API documentation from Python docstrings .\" ================== SYNOPSIS ==================== .SH SYNOPSIS .HP 7 .B epydoc .RB [ action ] .RB [ options ] .IB names... .\" ================== DESCRIPTION ==================== .SH DESCRIPTION .B epydoc generates API documentation for Python modules and packages, based on their docstrings. A lightweight markup language called .B epytext can be used to format docstrings, and to add information about specific fields, such as parameters and instance variables. Epydoc also understands docstrings written in ReStructuredText, Javadoc, and plaintext. Currently, epydoc supports two basic output formats: HTML and LaTeX. .PP The HTML API documentation produced by .B epydoc consists of a set of HTML files, including: an API documentation page for each class and module; a syntax-highlighted source code page for each module; an identifier index page; a help page; and a frames-based table of contents. When appropriate, .B epydoc will also generate index pages for bugs, defined terms, and to-do items; a class hierarchy page; and a package hierarchy page. .PP The LaTeX API documentation produced by .B epydoc consists of a main LaTeX file, and a LaTeX file for each module. If you use .BR \-\-dvi , .BR \-\-ps , or .B \-\-pdf , then .B epydoc will invoke external commands to convert the LaTeX output to the requested format. Note that the LaTeX files containing the documentation for individual modules can be included as chapters or sections of other LaTeX documents, using the LaTeX .B \\\\include command. If you wish to include individual classes in other LaTeX documents, then use the .B \-\-separate\-classes option to produce a separate LaTeX file for each class. .PP .B epydoc can also be used to check the completeness of the API documentation. By default, it checks that every public package, module, class, method, and function has a docstring description. The .B \-\-tests option can be used to specify additional tests to perform. .PP .\" ================== OPTIONS ==================== .SH OPTIONS Epydoc's options are divided into six categories: basic options, actions, generation options, output options, graph options, and return value options. .PP .\"-------------------------------------------------- .B BASIC OPTIONS .RS 4 .TP .IR names ... The list of objects that should be documented. Objects can be specified using Python dotted names (such as .BR os.path ), filenames (such as .BR epydoc/epytext.py ), or directory names (such as .BR epydoc/ ). Directory names specify packages, and are expanded to include all sub-modules and sub-packages. If you wish to exclude certain sub-modules or sub-packages, use the .B --exclude option (described below). .\" --config .TP .BI "\-\-config " file A configuration file, specifying additional .BR options "and/or" names "." This option may be repeated. .\" --quiet .TP .B \-\-q, \-\-quiet, \-\-v, \-\-verbose Produce quite (or verbose) output. If used multiple times, this option produces successively more quiet (or verbose) output. .\" --debug .TP .B \-\-debug Show full tracebacks for internal errors. .\" --simple-term .TP .B \-\-simple\-term Do not try to use color or cursor control when displaying the progress bar, warnings, or errors. .RE .PP .\"-------------------------------------------------- .B ACTIONS .RS 4 .TP 10 .B \-\-html Write HTML output. .B [default] .TP 10 .B \-\-latex Write LaTeX output. .TP 10 .B \-\-dvi Write DVI output. .TP 10 .B \-\-ps Write Postscript output. .TP 10 .B \-\-pdf Write Adobe Acrobat (pdf) output. .TP 10 .B \-\-check Perform completeness checks on the documentation. .TP 10 .B \-\-pickle Write the documentation to a pickle file. .RE .PP .\"-------------------------------------------------- .B GENERATION OPTIONS .RS 4 .\" --docformat .TP .BI "\-\-docformat " format Set the default value for .B __docformat__ to .IR format . .B __docformat__ is a module variable that specifies the markup language for the docstrings in a module. Its value consists of the name of a markup language, optionally followed by a language code (such as .B en for English). For a list of the markup languages currently recognized by epydoc, run .BR "epydoc \-\-help docformat" . .\" --parse-only .TP .BI "\-\-parse-only" Gather all information about the documented objects by parsing the relevant Python source code; in particular, do .I not use introspection to gather information about the documented objects. This option should be used when epydoc is run on untrusted code; or on code that can not be introspected because of missing dependencies, or because importing it would cause undesired side-effects. .\" --introspect-only .TP .BI "\-\-introspect-only" Gather all information about the documented objects by introspection; in particular, do .I not gather information by parsing the object's Python source code. .\" --exclude=PATTERN .TP .BI "\-\-exclude " PATTERN Do not document any object whose name matches the given regular expression pattern. .\" --exclude-introspect=PATTERN .TP .BI "\-\-exclude-introspect " PATTERN Do not use introspection to gather information about any object whose name matches the given regular expression. .\" --exclude-parse=PATTERN .TP .BI "\-\-exclude-parse " PATTERN Do not use Python source code parsing to gather information about any object whose name matches the given regular expression. .\" --inheritance .TP .BI "\-\-inheritance " format The format that should be used to display inherited methods, variables, and properties in the generated "summary" tables. If .I format is "grouped," then inherited objects are gathered into groups, based on which class that they are inherited from. If .I format is "listed," then inherited objects are listed in a short list at the end of the summary table. If .I format is "included," then inherited objects are mixed in with non-inherited objects. The default format for HTML output is "grouped." .\" --show-private, --no-private .TP .B \-\-show\-private, \-\-no\-private These options control whether documentation is generated for private objects. By default, the generated documentation includes private objects, and users can choose whether to view private objects or not, by clicking on "show private" and "hide private" links. But if you want to discourage users from directly accessing private objects, then you may prefer not to generate documentation for private objects. .\" --show-imports .TP .B \-\-show-imports, \-\-no\-imports These options control whether module imports are included in the generated documentation. By default, imports are not included. .\" --show-sourcecode .TP .B \-\-show\-sourcecode, \-\-no\-sourcecode These options control whether or not epydoc should generate syntax-highlighted pages containing the souce code of each module in the HTML output. By default, the sourcecode pages are generated. .\" --include-log .TP .B \-\-include\-log Generate an HTML page .B epydoc\-log.html containing all error and warning messages that are generated by epydoc, and include it in the generated output. .RE .PP .\"-------------------------------------------------- .B OUTPUT OPTIONS .RS 4 .\" --output .TP .BI "\-o " dir ", \-\-output " dir The output directory. If .B dir does not exist, then it will be created. If no output directory is specified, then the action name (e.g., .BR html " or " pdf ). .B html .\" --css .TP .BI "\-c " sheet ", \-\-css " sheet CSS stylesheet for HTML output files. If .I sheet is a file, then the stylesheet is copied from that file; otherwise, .I sheet is taken to be the name of a built\-in stylesheet. For a list of the built\-in stylesheets, run .BR "epydoc \-\-help css" . If a CSS stylesheet is not specified, then the default stylesheet is used. .\" --name .TP .BI "\-n " name ", \-\-name " name The name of the project whose documentation is being generated. .\" --url .TP .BI "\-u " url ", \-\-url " url The URL of the project's homepage. .TP .\" --navlink .TP .BI "\-\-navlink " html HTML code for the homepage link on the HTML navigation bar. If this HTML code contains any hyperlinks .RB ( "" ), then it will be inserted verbatim. If it does not contain any hyperlinks, and a project url is specified (with .BR \-\-url ), then a hyperlink to the specified URL is added to the link. .\" --help-file .TP .BI "\-\-help\-file " file An alternate help file. .B file should contain the body of an HTML file -- navigation bars will be added to it. .\" --show-frames, --no-frames .TP .B \-\-show\-frames, \-\-no\-frames These options control whether HMTL output will include a frames-base table of contents page. By default, the frames-based table of contents is included. .\" --separate-classes .TP .B \-\-separate\-classes In the LaTeX output, describe each class in a separate section of the documentation, instead of including them in the documentation for their modules. This creates a separate LaTeX file for each class, so it can also be useful if you want to include the documentation for one or two classes as sections of your own LaTeX document. .RE .PP .\"-------------------------------------------------- .B GRAPH OPTIONS .RS 4 .\" --graph .TP .BI "\-\-graph " graphtype Include graphs of type .B graphtype in the generated output. Graphs are generated using the Graphviz dot executable. If this executable is not on the path, then use .B \-\-dotpath to specify its location. This option may be repeated to include multiple graph types in the output. .B graphtype should be one of: .BR all ", " classtree ", " callgraph ", or " umlclasstree . .\" --dotpath .TP .BI "\-\-dotpath " path The path to the Graphviz .BR dot executable. .\"--graph-font .TP .BI "--graph-font " font The name of the font used to generate Graphviz graphs. (e.g., helvetica or times). .\"--graph-font-size .TP .BI "--graph-font-size " size The size of the font used to generate Graphviz graphs, in points. .\"--pstat .TP .BI "--pstat " file A pstat output file, to be used in generating call graphs. .RE .PP .\"-------------------------------------------------- .B RETURN VALUE OPTIONS .RS 4 .\" --fail-on-error .TP .B \-\-fail\-on\-error Return a non\-zero exit status, indicating failure, if any errors are encountered. .\" --fail-on-warning .TP .B \-\-fail\-on\-warning Return a non\-zero exit status, indicating failure, if any errors or warnings are encountered (not including docstring warnings). .\" --fail-on-docstring-warning .TP .B \-\-fail\-on\-docstring\-warning Return a non\-zero exit status, indicating failure, if any errors or warnings are encountered (including docstring warnings). .RE .\" ================== HTML FILES ==================== .SH HTML FILES The HTML API documentation produced by .B epydoc consists of the following files: .PP .B OBJECT DOCUMENTATION PAGES .RS 4 .TP .B index.html The standard entry point for the documentation. Normally, .B index.html is a copy of the frames file .RB ( frames.html ). But if the .B \-\-no\-frames option is used, then .B index.html is a copy of the API documentation home page, which is normally the documentation page for the top-level package or module (or the trees page if there is no top-level package or module). .TP .IB module \-module.html The API documentation for a module. .I module is the complete dotted name of the module, such as .B sys or .BR epydoc.epytext . .TP .IB class \-class.html The API documentation for a class, exception, or type. .I class is the complete dotted name of the class, such as .B epydoc.epytext.Token or .BR array.ArrayType . .TP .IB module \-pysrc.html A syntax-highlighted page containing the Python source code for .IR module . This page includes links back to the API documentation pages. .TP .B module-tree.html The module hierarchy. .TP .B class-tree.html The class hierarchy. This page is only generated if at least one class is documented. .PP .RE .B INDICES .RS 4 .TP .B identifier-index.html An index of all documented identifiers. If the identifier index contains more than 3,000 entries, then it will be split into separate pages for each letter, named .BR identifier-index-a.html , .BR identifier-index-b.html ", etc." .TP .B term-index.html An index of all explicitly marked definitional terms. This page is only generated if at least one definition term is marked in a formatted docstring. .TP .B bug-index.html An index of all explicitly marked .B @bug fields. This page is only generated if at least one .B @bug field is listed in a formatted docstring. .TP .B todo-index.html An index of all explicitly marked .B @todo fields. This page is only generated if at least one .B @todo field is listed in a formatted docstring. .TP .B changed-index.html An index of all explicitly marked .B @changed fields. This page is only generated if at least one .B @changed field is listed in a formatted docstring. .TP .B deprecated-index.html An index of all explicitly marked .B @deprecated fields. This page is only generated if at least one .B @deprecated field is listed in a formatted docstring. .TP .B since-index.html An index of all explicitly marked .B @since fields. This page is only generated if at least one .B @since field is listed in a formatted docstring. .RE .PP .B FRAMES-BASED TABLE OF CONTENTS .RS 4 .TP .B frames.html The main frames file. Two frames on the left side of the window contain a table of contents, and the main frame on the right side of the window contains API documentation pages. .TP .B toc.html The top\-level table of contents page. This page is displayed in the upper\-left frame of .BR frames.html , and provides links to the .B toc\-everything.html and .BI toc\- module \-module.html pages. .TP .B toc\-everything.html The table of contents for the entire project. This page is displayed in the lower\-left frame of .BR frames.html , and provides links to every class, type, exception, function, and variable defined by the project. .TP .BI toc\- module \-module.html The table of contents for a module. This page is displayed in the lower\-left frame of .BR frames.html , and provides links to every class, type, exception, function, and variable defined by the module. .I module is the complete dotted name of the module, such as .B sys or .BR epydoc.epytext . .RE .PP .B OTHER PAGES .RS 4 .TP .B help.html The help page for the project. This page explains how to use and navigate the webpage produced by epydoc. .TP .B redirect.html This page uses javascript to translate dotted names to their corresponding URLs. For example, in epydoc's documentation, loading the page .B will automatically redirect the browser to .BR . .TP .B epydoc.css The CSS stylesheet used to display all HTML pages. .TP .B epydoc.js A javascript file used to define javascript functions used by epydoc. .TP .B epydoc\-log.html A page containing a log of all warnings and errors that were generated by epydoc, along with a table listing all of the options that were used. .\" ================== LATEX FILES ==================== .SH LATEX FILES The LaTeX API documentation produced by .B epydoc consists of the following files: .RS 4 .TP .B api.pdf An Adobe Acrobat (pdf) file containing the complete API documentation. This file is only generated if you use the .B \-\-pdf option. .TP .B api.tex The top-level LaTeX file. This file imports the other LaTeX files, to create a single unified document. .TP .B api.dvi A dvi file containing the complete API documentation. This file is only generated if you use the .B \-\-dvi option, the .B \-\-ps option, or the .B \-\-pdf option. .TP .B api.ps A postscript file containing the complete API documentation. This file is only generated if you use the .B \-\-ps option or the .B \-\-pdf option. .TP .IB module -module.tex The API documentation for a module. .I module is the complete dotted name of the module, such as .B sys or .BR epydoc.epytext . .TP .IB class -class.tex The API documentation for a class, exception, or type. .I class is the complete dotted name of the class, such as .B epydoc.epytext.Token or array.ArrayType. These class documentation files are only created if the .B \-\-separate\-classes option is used; otherwise, the documentation for each class is included in its module's documentation file. .RE .\" ================== DIAGNOSTICS ==================== .SH DIAGNOSTICS .B EPYTEXT MARKUP WARNING MESSAGES .RS 4 Epytext errors are caused by epytext docstrings that contain invalid markup. Whenever an epytext error is detected, the docstring in question is treated as a plaintext docstring. Epydoc can generate the following epytext errors: .TP .B Bad link target. The target specified for an inline link contruction .RB ( "L{...}" ) is not well-formed. Link targets must be valid python identifiers. .TP .B Bad uri target. The target specified for an inline uri contruction .RB ( "U{...}" ) is not well-formed. This typically occurs if inline markup is nested inside the URI target. .TP .B Fields must be at the top level. The list of fields .RB "(" @param ", etc.)" is contained by some other block structure (such as a list or a section). .TP .B Fields must be the final elements. The list of fields .RB "(" @param ", etc.)" is not at the end of a docstring. .TP .B Headings must occur at top level. The heading is contianed in some other block structure (such as a list). .TP .B Improper doctest block indentation. The doctest block dedents past the indentation of its initial prompt line. .TP .B Improper heading indentation. The heading for a section is not left-aligned with the paragraphs in the section that contains it. .TP .B Improper paragraph indentation. The paragraphs within a block are not left-aligned. This error is often generated when plaintext docstrings are parsed using epytext. .TP .B Invalid escape. An unknown escape sequence was used with the inline escape construction .RB ( "E{...}" ). .TP .B Lists must be indented. An unindented line immediately following a paragraph starts with a list bullet. Epydoc is not sure whether you meant to start a new list item, or meant for a paragraph to include a word that looks like a bullet. If you intended the former, then indent the list. If you intended the latter, then change the word-wrapping of the paragraph, or escape the first character of the word that looks like a bullet. .TP .B Unbalanced '{'. The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace). .TP .B Unbalanced '}'. The docstring contains unbalanced braces. Epytext requires that all braces must be balanced. To include a single unbalanced brace, use the escape sequences E{lb} (left brace) and E{rb} (right brace). .TP .B Unknown inline markup tag. An unknown tag was used with the inline markup construction ( .IB x {...} ). .TP .B Wrong underline character for heading. The underline character used for this section heading does not indicate an appopriate section level. The "=" character should be used to underline sections; "-" for subsections; and "~" for subsubsections. .TP .B Possible mal-formatted field item. Epytext detected a line that looks like a field item, but is not correctly formatted. This typically occurs when the trailing colon (":") is not included in the field tag. .TP .B Possible heading typo. Epytext detected a pair of lines that looks like a heading, but the number of underline characters does not match the number of characters in the heading. The number of characters in these two lines must match exactly for them to be considered a heading. .RE .PP .B FIELD WARNINGS .RS 4 Field warnings are caused by docstrings containing invalid fields. The contents of the invalid field are generally ignored. Epydoc can generate the following field warnings: .TP .BI "@param for unknown parameter " param . A @param field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name. .TP .IB tag " did not expect an argument." The field tag .I tag was used with an argument, but it does not take one. .TP .IB tag " expected an argument." The field tag .I tag was used without an argument, but it requires one. .TP .BI "@type for unknown parameter " param . A @type field was used to specify the type for a parameter that is not included in the function's signature. This is typically caused by a typo in the parameter name. .TP .BI "@type for unknown variable " var . A @type field was used to specify the type for a variable, but no other information is known about the variable. This is typically caused by a typo in the variable name. .TP .BI "Unknown field tag " tag . A docstring contains a field with the unknown tag .IR tag . .TP .BI "Redefinition of " field . Multiple field tags define the value of .I field in the same docstring, but .I field can only take a single value. .RE .\" ================== EXAMPLES ==================== .SH EXAMPLES .TP .BR "epydoc \-n " epydoc " \-u " "http://epydoc.sf.net epydoc/" Generate the HTML API documentation for the epydoc package and all of its submodules, and write the output to the .B html directory. In the headers and footers, use .B epydoc as the project name, and .B http://epydoc.sf.net as the project URL. .TP .BR "epydoc \-\-pdf \-n " epydoc " epydoc/" Generate the LaTeX API documentation for the epydoc package and all of its submodules, and write the output to the .B latex directory. .\" ================== EXIT STATUS ==================== .SH EXIT STATUS .TP .B 0 Successful program execution. .TP .B 1 Usage error. .TP .B 2 Epydoc generated an error or warning, and one of the options .BI \-\-fail\-on\-error , .BI \-\-fail\-on\-warning ", or" .B \-\-fail\-on\-docstring\-warning was specified. .TP .B other Internal error (Python exception). .\" ================== AUTHOR ==================== .SH AUTHOR Epydoc was written by Edward Loper. This man page was originally written by Moshe Zadka, and is currently maintained by Edward Loper. .\" ================== BUGS ==================== .SH BUGS Report bugs to . .\" ================== SEE ALSO ==================== .SH SEE ALSO .BR epydocgui (1) .TP .B The epydoc webpage .TP .B The epytext markup language manual epydoc-3.0.1+dfsg/PKG-INFO0000644000175000017500000000043710750103105015266 0ustar pronovicpronovicMetadata-Version: 1.0 Name: epydoc Version: 3.0.1 Summary: Edward Loper's API Documentation Generation Tool Home-page: http://epydoc.sourceforge.net Author: Edward Loper Author-email: edloper@gradient.cis.upenn.edu License: IBM Open Source License Description: UNKNOWN Platform: UNKNOWN epydoc-3.0.1+dfsg/scripts/0002755000175000017500000000000010750103105015656 5ustar pronovicpronovicepydoc-3.0.1+dfsg/scripts/epydoc.pyw0000644000175000017500000000072310675045344017722 0ustar pronovicpronovic#!/usr/bin/env python # # Call the graphical interface for Epydoc. # # We have to do some path magic to prevent Python from getting # confused about the difference between this epydoc module, and the # real epydoc package. So sys.path[0], which contains the directory # of the script. import sys, os.path script_path = os.path.abspath(sys.path[0]) sys.path = [p for p in sys.path if os.path.abspath(p) != script_path] from epydoc.gui import gui gui() epydoc-3.0.1+dfsg/scripts/.cvsignore0000644000175000017500000000000510654406442017664 0ustar pronovicpronovic*.pycepydoc-3.0.1+dfsg/scripts/epydocgui0000644000175000017500000000014710675045355017613 0ustar pronovicpronovic#!/usr/bin/env python # # Call the graphical interface for Epydoc. # from epydoc.gui import gui gui() epydoc-3.0.1+dfsg/scripts/epydoc0000755000175000017500000000046110675045315017104 0ustar pronovicpronovic#!/usr/bin/env python # # Call the command line interface for Epydoc. # # Make sure that we don't get confused between an epydoc.py script and # the real epydoc package. import sys, os.path if os.path.exists(os.path.join(sys.path[0], 'epydoc.py')): del sys.path[0] from epydoc.cli import cli cli() epydoc-3.0.1+dfsg/scripts/apirst2html.py0000755000175000017500000000266210654406442020525 0ustar pronovicpronovic#!/usr/bin/env python # -*- coding: iso-8859-1 -*- """An HTML writer supporting link to external documentation. This module is a frontend for the Docutils_ HTML writer. It allows a document to reference objects documented in the API documentation generated by extraction tools such as Doxygen_ or Epydoc_. .. _Docutils: http://docutils.sourceforge.net/ .. _Doxygen: http://www.doxygen.org/ .. _Epydoc: http://epydoc.sourceforge.net/ """ # $Id: apirst2html.py 1531 2007-02-18 23:07:25Z dvarrazzo $ __version__ = "$Revision: 1531 $"[11:-2] __author__ = "Daniele Varrazzo" __copyright__ = "Copyright (C) 2007 by Daniele Varrazzo" __docformat__ = 'reStructuredText en' try: import locale locale.setlocale(locale.LC_ALL, '') except: pass # We have to do some path magic to prevent Python from getting # confused about the difference between the ``epydoc.py`` script, and the # real ``epydoc`` package. So remove ``sys.path[0]``, which contains the # directory of the script. import sys, os.path script_path = os.path.abspath(sys.path[0]) sys.path = [p for p in sys.path if os.path.abspath(p) != script_path] import epydoc.docwriter.xlink as xlink from docutils.core import publish_cmdline, default_description description = ('Generates (X)HTML documents with API documentation links. ' + default_description) publish_cmdline(reader=xlink.ApiLinkReader(), writer_name='html', description=description) epydoc-3.0.1+dfsg/scripts/epydoc.pyc0000644000175000017500000000065410750073323017671 0ustar pronovicpronovicmò ÃJôFc@s‡dkZdkZeiieidƒZgZeiD]*Zeiieƒejo eeq9q9[e_dkl Z e ƒdS(Ni(scli( tsystos.pathtostpathtabspatht script_patht_[1]tpt epydoc.clitcli(RR RRRR((t;/home/edloper/newdata/projects/epydoc/src/scripts/epydoc.pyt? sD epydoc-3.0.1+dfsg/scripts/epydoc.py0000644000175000017500000000073510675045303017531 0ustar pronovicpronovic#!/usr/bin/env python # # Call the command line interface for Epydoc. # # We have to do some path magic to prevent Python from getting # confused about the difference between this epydoc module, and the # real epydoc package. So remove sys.path[0], which contains the # directory of the script. import sys, os.path script_path = os.path.abspath(sys.path[0]) sys.path = [p for p in sys.path if os.path.abspath(p) != script_path] from epydoc.cli import cli cli()