From 2c4c20436e7f6c8a65185697455bd85bc5d6f585 Mon Sep 17 00:00:00 2001 From: James Taylor Date: Wed, 15 Nov 2006 18:27:21 +0000 Subject: [PATCH] Cleaning up modules. Still a few stragglers that can't be easily eggified. EVERYTHING we depend on should eventually be under the galaxy module or packaged in eggs to avoid namespace problems. --- {modules => lib}/cookbook/__init__.py | 0 {modules => lib}/cookbook/doc_optparse.py | 0 {modules => lib}/cookbook/odict.py | 0 {modules => lib}/cookbook/path.py | 0 {modules => lib}/cookbook/patterns.py | 0 {modules => lib}/fpconst.py | 0 lib/galaxy/{util.py => util/__init__.py} | 3 +- lib/galaxy/util/docutils_ext/__init__.py | 0 lib/galaxy/util/docutils_ext/htmlfrag.py | 137 ++++ {modules => lib}/pkg_resources.py | 0 {modules => lib}/psyco_full.py | 0 modules/coverage.py | 824 ---------------------- modules/ez_setup.py | 219 ------ modules/misc.py | 9 - nosetests.sh | 2 +- run.sh | 2 +- nosetests.py => scripts/nosetests.py | 0 paster.py => scripts/paster.py | 0 {modules => scripts}/rst2html.py | 0 19 files changed, 141 insertions(+), 1055 deletions(-) rename {modules => lib}/cookbook/__init__.py (100%) rename {modules => lib}/cookbook/doc_optparse.py (100%) rename {modules => lib}/cookbook/odict.py (100%) rename {modules => lib}/cookbook/path.py (100%) rename {modules => lib}/cookbook/patterns.py (100%) rename {modules => lib}/fpconst.py (100%) rename lib/galaxy/{util.py => util/__init__.py} (97%) create mode 100644 lib/galaxy/util/docutils_ext/__init__.py create mode 100644 lib/galaxy/util/docutils_ext/htmlfrag.py rename {modules => lib}/pkg_resources.py (100%) rename {modules => lib}/psyco_full.py (100%) delete mode 100644 modules/coverage.py delete mode 100644 modules/ez_setup.py delete mode 100644 modules/misc.py rename nosetests.py => scripts/nosetests.py (100%) rename paster.py => scripts/paster.py (100%) rename {modules => scripts}/rst2html.py (100%) diff --git a/modules/cookbook/__init__.py b/lib/cookbook/__init__.py similarity index 100% rename from modules/cookbook/__init__.py rename to lib/cookbook/__init__.py diff --git a/modules/cookbook/doc_optparse.py b/lib/cookbook/doc_optparse.py similarity index 100% rename from modules/cookbook/doc_optparse.py rename to lib/cookbook/doc_optparse.py diff --git a/modules/cookbook/odict.py b/lib/cookbook/odict.py similarity index 100% rename from modules/cookbook/odict.py rename to lib/cookbook/odict.py diff --git a/modules/cookbook/path.py b/lib/cookbook/path.py similarity index 100% rename from modules/cookbook/path.py rename to lib/cookbook/path.py diff --git a/modules/cookbook/patterns.py b/lib/cookbook/patterns.py similarity index 100% rename from modules/cookbook/patterns.py rename to lib/cookbook/patterns.py diff --git a/modules/fpconst.py b/lib/fpconst.py similarity index 100% rename from modules/fpconst.py rename to lib/fpconst.py diff --git a/lib/galaxy/util.py b/lib/galaxy/util/__init__.py similarity index 97% rename from lib/galaxy/util.py rename to lib/galaxy/util/__init__.py index c58a1576691..1ee4305af3b 100644 --- a/lib/galaxy/util.py +++ b/lib/galaxy/util/__init__.py @@ -9,6 +9,7 @@ import pkg_resources pkg_resources.require( 'docutils' ) import docutils.core +from galaxy.util.docutils_ext.htmlfrag import Writer as HTMLFragWriter pkg_resources.require( 'elementtree' ) from elementtree import ElementTree @@ -205,7 +206,7 @@ def rst_to_html( s ): def write( self, str ): if len( str ) > 0 and not str.isspace(): log.warn( str ) - return docutils.core.publish_string( s, writer_name="htmlfrag", settings_overrides=dict( warning_stream=FakeStream() ) ) + return docutils.core.publish_string( s, writer=HTMLFragWriter(), settings_overrides=dict( warning_stream=FakeStream() ) ) def xml_text(root, name): """Returns the text inside an element""" diff --git a/lib/galaxy/util/docutils_ext/__init__.py b/lib/galaxy/util/docutils_ext/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/galaxy/util/docutils_ext/htmlfrag.py b/lib/galaxy/util/docutils_ext/htmlfrag.py new file mode 100644 index 00000000000..8df0169b8a7 --- /dev/null +++ b/lib/galaxy/util/docutils_ext/htmlfrag.py @@ -0,0 +1,137 @@ +# Author: Ollie Rutherfurd +# Contact: oliver@rutherfurd.net +# Revision: $Revision: 2884 $ +# Date: $Date: 2004-12-08 20:49:05 +0100 (Wed, 08 Dec 2004) $ +# Copyright: This module has been placed in the public domain. + +""" +Simple .ht (HyperText Template) document tree Writer. + +.ht tmeplate files are essentially normal HTML, with +an option set of RFC 2822-like headers at the top of +the file. There must be at least one blank line between +the last header and the start of the body HTML. + +See http://ht2html.sf.net/ for more information on +.ht files and ht2html.. +""" + +__docformat__ = 'reStructuredText' + +import os +from docutils import nodes +from docutils import writers +from docutils import frontend +from docutils.writers.html4css1 import HTMLTranslator, utils + + +class Writer(writers.Writer): + + supported = ('htmlfrag',) + """Formats this writer supports.""" + + settings_spec = ( + 'HTML-Specific Options', + None, + (('Specify a stylesheet URL, used verbatim. Default is ' + '"default.css". Overrides --stylesheet-path.', + ['--stylesheet'], + {'default': 'default.css', 'metavar': '', + 'overrides': 'stylesheet_path'}), + ('Specify a stylesheet file, relative to the current working ' + 'directory. The path is adjusted relative to the output HTML ' + 'file. Overrides --stylesheet.', + ['--stylesheet-path'], + {'metavar': '', 'overrides': 'stylesheet'}), + ('Link to the stylesheet in the output HTML file. This is the ' + 'default.', + ['--link-stylesheet'], + {'dest': 'embed_stylesheet', 'action': 'store_false', + 'validator': frontend.validate_boolean}), + ('Embed the stylesheet in the output HTML file. The stylesheet ' + 'file must be accessible during processing (--stylesheet-path is ' + 'recommended). Default: link the stylesheet, do not embed it.', + ['--embed-stylesheet'], + {'action': 'store_true', 'validator': frontend.validate_boolean}), + ('Specify the initial header level. Default is 1 for "

". ' + 'Does not affect document title & subtitle (see --no-doc-title).', + ['--initial-header-level'], + {'choices': '1 2 3 4 5 6'.split(), 'default': '3', + 'metavar': ''}), + ('Specify the maximum width (in characters) for one-column field ' + 'names. Longer field names will span an entire row of the table ' + 'used to render the field list. Default is 14 characters. ' + 'Use 0 for "no limit".', + ['--field-name-limit'], + {'default': 14, 'metavar': '', + 'validator': frontend.validate_nonnegative_int}), + ('Specify the maximum width (in characters) for options in option ' + 'lists. Longer options will span an entire row of the table used ' + 'to render the option list. Default is 14 characters. ' + 'Use 0 for "no limit".', + ['--option-limit'], + {'default': 14, 'metavar': '', + 'validator': frontend.validate_nonnegative_int}), + ('Format for footnote references: one of "superscript" or ' + '"brackets". Default is "brackets".', + ['--footnote-references'], + {'choices': ['superscript', 'brackets'], 'default': 'brackets', + 'metavar': '', + 'overrides': 'trim_footnote_reference_space'}), + ('Format for block quote attributions: one of "dash" (em-dash ' + 'prefix), "parentheses"/"parens", or "none". Default is "dash".', + ['--attribution'], + {'choices': ['dash', 'parentheses', 'parens', 'none'], + 'default': 'dash', 'metavar': ''}), + ('Remove extra vertical whitespace between items of bullet lists ' + 'and enumerated lists, when list items are "simple" (i.e., all ' + 'items each contain one paragraph and/or one "simple" sublist ' + 'only). Default: enabled.', + ['--compact-lists'], + {'default': 1, 'action': 'store_true', + 'validator': frontend.validate_boolean}), + ('Disable compact simple bullet and enumerated lists.', + ['--no-compact-lists'], + {'dest': 'compact_lists', 'action': 'store_false'}), + ('Omit the XML declaration. Use with caution.', + ['--no-xml-declaration'], + {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false', + 'validator': frontend.validate_boolean}), + ('Scramble email addresses to confuse harvesters. ' + 'For example, "abc@example.org" will become ' + '``abc at example dot org``.', + ['--cloak-email-addresses'], + {'action': 'store_true', 'validator': frontend.validate_boolean}),)) + + + relative_path_settings = ('stylesheet_path',) + + output = None + + def __init__(self): + writers.Writer.__init__(self) + self.translator_class = HTMLFragTranslator + + def translate(self): + visitor = self.translator_class(self.document) + self.document.walkabout(visitor) + self.output = visitor.astext() + self.stylesheet = visitor.stylesheet + self.body = visitor.body + + +class HTMLFragTranslator(HTMLTranslator): + + def __init__(self, document): + # I don't believe we can embed any style content + # the header, so always link to the stylesheet. + document.settings.embed_stylesheet = 0 + HTMLTranslator.__init__(self, document) + + def astext(self): + # kludge! want footer, but not '' + body = self.body_pre_docinfo + self.docinfo + self.body + \ + self.body_suffix[:-1] + return ''.join(body) + +# :indentSize=4:lineSeparator=\n:noTabs=true:tabSize=4: diff --git a/modules/pkg_resources.py b/lib/pkg_resources.py similarity index 100% rename from modules/pkg_resources.py rename to lib/pkg_resources.py diff --git a/modules/psyco_full.py b/lib/psyco_full.py similarity index 100% rename from modules/psyco_full.py rename to lib/psyco_full.py diff --git a/modules/coverage.py b/modules/coverage.py deleted file mode 100644 index 28d8e3a5ea4..00000000000 --- a/modules/coverage.py +++ /dev/null @@ -1,824 +0,0 @@ -#!/usr/bin/python -# -# Perforce Defect Tracking Integration Project -# -# -# COVERAGE.PY -- COVERAGE TESTING -# -# Gareth Rees, Ravenbrook Limited, 2001-12-04 -# Ned Batchelder, 2004-12-12 -# http://nedbatchelder.com/code/modules/coverage.html -# -# -# 1. INTRODUCTION -# -# This module provides coverage testing for Python code. -# -# The intended readership is all Python developers. -# -# This document is not confidential. -# -# See [GDR 2001-12-04a] for the command-line interface, programmatic -# interface and limitations. See [GDR 2001-12-04b] for requirements and -# design. - -"""Usage: - -coverage.py -x MODULE.py [ARG1 ARG2 ...] - Execute module, passing the given command-line arguments, collecting - coverage data. - -coverage.py -e - Erase collected coverage data. - -coverage.py -r [-m] FILE1 FILE2 ... - Report on the statement coverage for the given files. With the -m - option, show line numbers of the statements that weren't executed. - -coverage.py -a [-d dir] FILE1 FILE2 ... - Make annotated copies of the given files, marking statements that - are executed with > and statements that are missed with !. With - the -d option, make the copies in that directory. Without the -d - option, make each copy in the same directory as the original. - -Coverage data is saved in the file .coverage by default. Set the -COVERAGE_FILE environment variable to save it somewhere else.""" - -__version__ = "2.2.20041231" # see detailed history at the end of this file. - -import compiler -import compiler.visitor -import os -import re -import string -import sys -import types - - -# 2. IMPLEMENTATION -# -# This uses the "singleton" pattern. -# -# The word "morf" means a module object (from which the source file can -# be deduced by suitable manipulation of the __file__ attribute) or a -# filename. -# -# When we generate a coverage report we have to canonicalize every -# filename in the coverage dictionary just in case it refers to the -# module we are reporting on. It seems a shame to throw away this -# information so the data in the coverage dictionary is transferred to -# the 'cexecuted' dictionary under the canonical filenames. -# -# The coverage dictionary is called "c" and the trace function "t". The -# reason for these short names is that Python looks up variables by name -# at runtime and so execution time depends on the length of variables! -# In the bottleneck of this application it's appropriate to abbreviate -# names to increase speed. - -# A dictionary with an entry for (Python source file name, line number -# in that file) if that line has been executed. -c = {} - -# t(f, x, y). This method is passed to sys.settrace as a trace -# function. See [van Rossum 2001-07-20b, 9.2] for an explanation of -# sys.settrace and the arguments and return value of the trace function. -# See [van Rossum 2001-07-20a, 3.2] for a description of frame and code -# objects. - -def t(f, w, a): - #print w, f.f_code.co_filename, f.f_lineno - if w == 'line': - c[(f.f_code.co_filename, f.f_lineno)] = 1 - return t - -class StatementFindingAstVisitor(compiler.visitor.ASTVisitor): - def __init__(self, statements, excluded, suite_spots): - compiler.visitor.ASTVisitor.__init__(self) - self.statements = statements - self.excluded = excluded - self.suite_spots = suite_spots - self.excluding_suite = 0 - - def doRecursive(self, node): - self.recordNodeLine(node) - for n in node.getChildNodes(): - self.dispatch(n) - - visitStmt = visitModule = doRecursive - - def doCode(self, node): - if hasattr(node, 'decorators') and node.decorators: - self.dispatch(node.decorators) - self.doSuite(node, node.code) - - visitFunction = visitClass = doCode - - def getFirstLine(self, node): - # Find the first line in the tree node. - lineno = node.lineno - for n in node.getChildNodes(): - f = self.getFirstLine(n) - if lineno and f: - lineno = min(lineno, f) - else: - lineno = lineno or f - return lineno - - def getLastLine(self, node): - # Find the first line in the tree node. - lineno = node.lineno - for n in node.getChildNodes(): - lineno = max(lineno, self.getLastLine(n)) - return lineno - - def doStatement(self, node): - self.recordLine(self.getFirstLine(node)) - - visitAssert = visitAssign = visitAssTuple = visitDiscard = visitPrint = \ - visitPrintnl = visitRaise = visitSubscript = \ - visitDecorators = \ - doStatement - - def recordNodeLine(self, node): - return self.recordLine(node.lineno) - - def recordLine(self, lineno): - # Returns a bool, whether the line is included or excluded. - if lineno: - # Multi-line tests introducing suites have to get charged to their - # keyword. - if lineno in self.suite_spots: - lineno = self.suite_spots[lineno][0] - # If we're inside an exluded suite, record that this line was - # excluded. - if self.excluding_suite: - self.excluded[lineno] = 1 - return 0 - # If this line is excluded, or suite_spots maps this line to - # another line that is exlcuded, then we're excluded. - elif self.excluded.has_key(lineno) or \ - self.suite_spots.has_key(lineno) and \ - self.excluded.has_key(self.suite_spots[lineno][1]): - return 0 - # Otherwise, this is an executable line. - else: - self.statements[lineno] = 1 - return 1 - return 0 - - default = recordNodeLine - - def recordAndDispatch(self, node): - self.recordNodeLine(node) - self.dispatch(node) - - def doSuite(self, intro, body, exclude=0): - exsuite = self.excluding_suite - if exclude or (intro and not self.recordNodeLine(intro)): - self.excluding_suite = 1 - self.recordAndDispatch(body) - self.excluding_suite = exsuite - - def doPlainWordSuite(self, prevsuite, suite): - # Finding the exclude lines for else's is tricky, because they aren't - # present in the compiler parse tree. Look at the previous suite, - # and find its last line. If any line between there and the else's - # first line are excluded, then we exclude the else. - lastprev = self.getLastLine(prevsuite) - firstelse = self.getFirstLine(suite) - for l in range(lastprev+1, firstelse): - if self.suite_spots.has_key(l): - self.doSuite(None, suite, exclude=self.excluded.has_key(l)) - break - else: - self.doSuite(None, suite) - - def doElse(self, prevsuite, node): - if node.else_: - self.doPlainWordSuite(prevsuite, node.else_) - - def visitFor(self, node): - self.doSuite(node, node.body) - self.doElse(node.body, node) - - def visitIf(self, node): - # The first test has to be handled separately from the rest. - # The first test is credited to the line with the "if", but the others - # are credited to the line with the test for the elif. - self.doSuite(node, node.tests[0][1]) - for t, n in node.tests[1:]: - self.doSuite(t, n) - self.doElse(node.tests[-1][1], node) - - def visitWhile(self, node): - self.doSuite(node, node.body) - self.doElse(node.body, node) - - def visitTryExcept(self, node): - self.doSuite(node, node.body) - for i in range(len(node.handlers)): - a, b, h = node.handlers[i] - if not a: - # It's a plain "except:". Find the previous suite. - if i > 0: - prev = node.handlers[i-1][2] - else: - prev = node.body - self.doPlainWordSuite(prev, h) - else: - self.doSuite(a, h) - self.doElse(node.handlers[-1][2], node) - - def visitTryFinally(self, node): - self.doSuite(node, node.body) - self.doPlainWordSuite(node.body, node.final) - - def visitGlobal(self, node): - # "global" statements don't execute like others (they don't call the - # trace function), so don't record their line numbers. - pass - -the_coverage = None - -class coverage: - error = "coverage error" - - # Name of the cache file (unless environment variable is set). - cache_default = ".coverage" - - # Environment variable naming the cache file. - cache_env = "COVERAGE_FILE" - - # A map from canonical Python source file name to a dictionary in - # which there's an entry for each line number that has been - # executed. - cexecuted = {} - - # Cache of results of calling the analysis2() method, so that you can - # specify both -r and -a without doing double work. - analysis_cache = {} - - # Cache of results of calling the canonical_filename() method, to - # avoid duplicating work. - canonical_filename_cache = {} - - def __init__(self): - global the_coverage - if the_coverage: - raise self.error, "Only one coverage object allowed." - self.usecache = 1 - self.cache = None - self.exclude_re = '' - - def help(self, error=None): - if error: - print error - print - print __doc__ - sys.exit(1) - - def command_line(self): - import getopt - settings = {} - optmap = { - '-a': 'annotate', - '-d:': 'directory=', - '-e': 'erase', - '-h': 'help', - '-i': 'ignore-errors', - '-m': 'show-missing', - '-r': 'report', - '-x': 'execute', - } - short_opts = string.join(map(lambda o: o[1:], optmap.keys()), '') - long_opts = optmap.values() - options, args = getopt.getopt(sys.argv[1:], short_opts, - long_opts) - for o, a in options: - if optmap.has_key(o): - settings[optmap[o]] = 1 - elif optmap.has_key(o + ':'): - settings[optmap[o + ':']] = a - elif o[2:] in long_opts: - settings[o[2:]] = 1 - elif o[2:] + '=' in long_opts: - settings[o[2:]] = a - else: - self.help("Unknown option: '%s'." % o) - if settings.get('help'): - self.help() - for i in ['erase', 'execute']: - for j in ['annotate', 'report']: - if settings.get(i) and settings.get(j): - self.help("You can't specify the '%s' and '%s' " - "options at the same time." % (i, j)) - args_needed = (settings.get('execute') - or settings.get('annotate') - or settings.get('report')) - action = settings.get('erase') or args_needed - if not action: - self.help("You must specify at least one of -e, -x, -r, or -a.") - if not args_needed and args: - self.help("Unexpected arguments %s." % args) - - self.get_ready() - self.exclude('#pragma[: ]+[nN][oO] [cC][oO][vV][eE][rR]') - - if settings.get('erase'): - self.erase() - if settings.get('execute'): - if not args: - self.help("Nothing to do.") - sys.argv = args - self.start() - import __main__ - sys.path[0] = os.path.dirname(sys.argv[0]) - execfile(sys.argv[0], __main__.__dict__) - if not args: - args = self.cexecuted.keys() - ignore_errors = settings.get('ignore-errors') - show_missing = settings.get('show-missing') - directory = settings.get('directory=') - if settings.get('report'): - self.report(args, show_missing, ignore_errors) - if settings.get('annotate'): - self.annotate(args, directory, ignore_errors) - - def use_cache(self, usecache): - self.usecache = usecache - - def get_ready(self): - if self.usecache and not self.cache: - self.cache = os.environ.get(self.cache_env, self.cache_default) - self.restore() - self.analysis_cache = {} - - def start(self): - self.get_ready() - sys.settrace(t) - - def stop(self): - sys.settrace(None) - - def erase(self): - global c - c = {} - self.analysis_cache = {} - self.cexecuted = {} - if self.cache and os.path.exists(self.cache): - os.remove(self.cache) - self.exclude_re = '' - - def exclude(self, re): - if self.exclude_re: - self.exclude_re += "|" - self.exclude_re += "(" + re + ")" - - # save(). Save coverage data to the coverage cache. - - def save(self): - if self.usecache and self.cache: - self.canonicalize_filenames() - cache = open(self.cache, 'wb') - import marshal - marshal.dump(self.cexecuted, cache) - cache.close() - - # restore(). Restore coverage data from the coverage cache (if it - # exists). - - def restore(self): - global c - c = {} - self.cexecuted = {} - assert self.usecache - if not os.path.exists(self.cache): - return - try: - cache = open(self.cache, 'rb') - import marshal - cexecuted = marshal.load(cache) - cache.close() - if isinstance(cexecuted, types.DictType): - self.cexecuted = cexecuted - except: - pass - - # canonical_filename(filename). Return a canonical filename for the - # file (that is, an absolute path with no redundant components and - # normalized case). See [GDR 2001-12-04b, 3.3]. - - def canonical_filename(self, filename): - if not self.canonical_filename_cache.has_key(filename): - f = filename - if os.path.isabs(f) and not os.path.exists(f): - f = os.path.basename(f) - if not os.path.isabs(f): - for path in [os.curdir] + sys.path: - g = os.path.join(path, f) - if os.path.exists(g): - f = g - break - cf = os.path.normcase(os.path.abspath(f)) - self.canonical_filename_cache[filename] = cf - return self.canonical_filename_cache[filename] - - # canonicalize_filenames(). Copy results from "executed" to - # "cexecuted", canonicalizing filenames on the way. Clear the - # "executed" map. - - def canonicalize_filenames(self): - global c - for filename, lineno in c.keys(): - f = self.canonical_filename(filename) - if not self.cexecuted.has_key(f): - self.cexecuted[f] = {} - self.cexecuted[f][lineno] = 1 - c = {} - - # morf_filename(morf). Return the filename for a module or file. - - def morf_filename(self, morf): - if isinstance(morf, types.ModuleType): - if not hasattr(morf, '__file__'): - raise self.error, "Module has no __file__ attribute." - file = morf.__file__ - else: - file = morf - return self.canonical_filename(file) - - # analyze_morf(morf). Analyze the module or filename passed as - # the argument. If the source code can't be found, raise an error. - # Otherwise, return a tuple of (1) the canonical filename of the - # source code for the module, (2) a list of lines of statements - # in the source code, and (3) a list of lines of excluded statements. - - def analyze_morf(self, morf): - if self.analysis_cache.has_key(morf): - return self.analysis_cache[morf] - filename = self.morf_filename(morf) - ext = os.path.splitext(filename)[1] - if ext == '.pyc': - if not os.path.exists(filename[0:-1]): - raise self.error, ("No source for compiled code '%s'." - % filename) - filename = filename[0:-1] - elif ext != '.py': - raise self.error, "File '%s' not Python source." % filename - source = open(filename, 'r') - lines, excluded_lines = self.find_executable_statements( - source.read(), exclude=self.exclude_re - ) - source.close() - result = filename, lines, excluded_lines - self.analysis_cache[morf] = result - return result - - def get_suite_spots(self, tree, spots): - import symbol, token - for i in range(1, len(tree)): - if type(tree[i]) == type(()): - if tree[i][0] == symbol.suite: - # Found a suite, look back for the colon and keyword. - lineno_colon = lineno_word = None - for j in range(i-1, 0, -1): - if tree[j][0] == token.COLON: - lineno_colon = tree[j][2] - elif tree[j][0] == token.NAME: - if tree[j][1] == 'elif': - # Find the line number of the first non-terminal - # after the keyword. - t = tree[j+1] - while t and token.ISNONTERMINAL(t[0]): - t = t[1] - if t: - lineno_word = t[2] - else: - lineno_word = tree[j][2] - break - elif tree[j][0] == symbol.except_clause: - # "except" clauses look like: - # ('except_clause', ('NAME', 'except', lineno), ...) - if tree[j][1][0] == token.NAME: - lineno_word = tree[j][1][2] - break - if lineno_colon and lineno_word: - # Found colon and keyword, mark all the lines - # between the two with the two line numbers. - for l in range(lineno_word, lineno_colon+1): - spots[l] = (lineno_word, lineno_colon) - self.get_suite_spots(tree[i], spots) - - def find_executable_statements(self, text, exclude=None): - # Find lines which match an exclusion pattern. - excluded = {} - suite_spots = {} - if exclude: - reExclude = re.compile(exclude) - lines = text.split('\n') - for i in range(len(lines)): - if reExclude.search(lines[i]): - excluded[i+1] = 1 - - import parser - tree = parser.suite(text+'\n\n').totuple(1) - self.get_suite_spots(tree, suite_spots) - - # Use the compiler module to parse the text and find the executable - # statements. We add newlines to be impervious to final partial lines. - statements = {} - ast = compiler.parse(text+'\n\n') - visitor = StatementFindingAstVisitor(statements, excluded, suite_spots) - compiler.walk(ast, visitor, walker=visitor) - - lines = statements.keys() - lines.sort() - excluded_lines = excluded.keys() - excluded_lines.sort() - return lines, excluded_lines - - # format_lines(statements, lines). Format a list of line numbers - # for printing by coalescing groups of lines as long as the lines - # represent consecutive statements. This will coalesce even if - # there are gaps between statements, so if statements = - # [1,2,3,4,5,10,11,12,13,14] and lines = [1,2,5,10,11,13,14] then - # format_lines will return "1-2, 5-11, 13-14". - - def format_lines(self, statements, lines): - pairs = [] - i = 0 - j = 0 - start = None - pairs = [] - while i < len(statements) and j < len(lines): - if statements[i] == lines[j]: - if start == None: - start = lines[j] - end = lines[j] - j = j + 1 - elif start: - pairs.append((start, end)) - start = None - i = i + 1 - if start: - pairs.append((start, end)) - def stringify(pair): - start, end = pair - if start == end: - return "%d" % start - else: - return "%d-%d" % (start, end) - import string - return string.join(map(stringify, pairs), ", ") - - # Backward compatibility with version 1. - def analysis(self, morf): - f, s, _, m, mf = self.analysis2(morf) - return f, s, m, mf - - def analysis2(self, morf): - filename, statements, excluded = self.analyze_morf(morf) - self.canonicalize_filenames() - if not self.cexecuted.has_key(filename): - self.cexecuted[filename] = {} - missing = [] - for line in statements: - if not self.cexecuted[filename].has_key(line): - missing.append(line) - return (filename, statements, excluded, missing, - self.format_lines(statements, missing)) - - def morf_name(self, morf): - if isinstance(morf, types.ModuleType): - return morf.__name__ - else: - return os.path.splitext(os.path.basename(morf))[0] - - def report(self, morfs, show_missing=1, ignore_errors=0): - if not isinstance(morfs, types.ListType): - morfs = [morfs] - max_name = max([5,] + map(len, map(self.morf_name, morfs))) - fmt_name = "%%- %ds " % max_name - fmt_err = fmt_name + "%s: %s" - header = fmt_name % "Name" + " Stmts Exec Cover" - fmt_coverage = fmt_name + "% 6d % 6d % 5d%%" - if show_missing: - header = header + " Missing" - fmt_coverage = fmt_coverage + " %s" - print header - print "-" * len(header) - total_statements = 0 - total_executed = 0 - for morf in morfs: - name = self.morf_name(morf) - try: - _, statements, _, missing, readable = self.analysis2(morf) - n = len(statements) - m = n - len(missing) - if n > 0: - pc = 100.0 * m / n - else: - pc = 100.0 - args = (name, n, m, pc) - if show_missing: - args = args + (readable,) - print fmt_coverage % args - total_statements = total_statements + n - total_executed = total_executed + m - except KeyboardInterrupt: - raise - except: - if not ignore_errors: - type, msg = sys.exc_info()[0:2] - print fmt_err % (name, type, msg) - if len(morfs) > 1: - print "-" * len(header) - if total_statements > 0: - pc = 100.0 * total_executed / total_statements - else: - pc = 100.0 - args = ("TOTAL", total_statements, total_executed, pc) - if show_missing: - args = args + ("",) - print fmt_coverage % args - - # annotate(morfs, ignore_errors). - - blank_re = re.compile("\\s*(#|$)") - else_re = re.compile("\\s*else\\s*:\\s*(#|$)") - - def annotate(self, morfs, directory=None, ignore_errors=0): - for morf in morfs: - print morf - try: - filename, statements, excluded, missing, _ = self.analysis2(morf) - self.annotate_file(filename, statements, excluded, missing, directory) - except KeyboardInterrupt: - raise - except: - if not ignore_errors: - raise - - def annotate_file(self, filename, statements, excluded, missing, directory=None): - source = open(filename, 'r') - if directory: - dest_file = os.path.join(directory, - os.path.basename(filename) - + ',cover') - else: - dest_file = filename + ',cover' - dest = open(dest_file, 'w') - lineno = 0 - i = 0 - j = 0 - covered = 1 - while 1: - line = source.readline() - if line == '': - break - lineno = lineno + 1 - while i < len(statements) and statements[i] < lineno: - i = i + 1 - while j < len(missing) and missing[j] < lineno: - j = j + 1 - if i < len(statements) and statements[i] == lineno: - covered = j >= len(missing) or missing[j] > lineno - if self.blank_re.match(line): - dest.write(' ') - elif self.else_re.match(line): - # Special logic for lines containing only - # 'else:'. See [GDR 2001-12-04b, 3.2]. - if i >= len(statements) and j >= len(missing): - dest.write('! ') - elif i >= len(statements) or j >= len(missing): - dest.write('> ') - elif statements[i] == missing[j]: - dest.write('! ') - else: - dest.write('> ') - elif lineno in excluded: - dest.write('- ') - elif covered: - dest.write('> ') - else: - dest.write('! ') - dest.write(line) - source.close() - dest.close() - -# Singleton object. -the_coverage = coverage() - -# Module functions call methods in the singleton object. -def use_cache(*args, **kw): return the_coverage.use_cache(*args, **kw) -def start(*args, **kw): return the_coverage.start(*args, **kw) -def stop(*args, **kw): return the_coverage.stop(*args, **kw) -def erase(*args, **kw): return the_coverage.erase(*args, **kw) -def exclude(*args, **kw): return the_coverage.exclude(*args, **kw) -def analysis(*args, **kw): return the_coverage.analysis(*args, **kw) -def analysis2(*args, **kw): return the_coverage.analysis2(*args, **kw) -def report(*args, **kw): return the_coverage.report(*args, **kw) -def annotate(*args, **kw): return the_coverage.annotate(*args, **kw) -def annotate_file(*args, **kw): return the_coverage.annotate_file(*args, **kw) - -# Save coverage data when Python exits. (The atexit module wasn't -# introduced until Python 2.0, so use sys.exitfunc when it's not -# available.) -try: - import atexit - atexit.register(the_coverage.save) -except ImportError: - sys.exitfunc = the_coverage.save - -# Command-line interface. -if __name__ == '__main__': - the_coverage.command_line() - - -# A. REFERENCES -# -# [GDR 2001-12-04a] "Statement coverage for Python"; Gareth Rees; -# Ravenbrook Limited; 2001-12-04; -# . -# -# [GDR 2001-12-04b] "Statement coverage for Python: design and -# analysis"; Gareth Rees; Ravenbrook Limited; 2001-12-04; -# . -# -# [van Rossum 2001-07-20a] "Python Reference Manual (releae 2.1.1)"; -# Guide van Rossum; 2001-07-20; -# . -# -# [van Rossum 2001-07-20b] "Python Library Reference"; Guido van Rossum; -# 2001-07-20; . -# -# -# B. DOCUMENT HISTORY -# -# 2001-12-04 GDR Created. -# -# 2001-12-06 GDR Added command-line interface and source code -# annotation. -# -# 2001-12-09 GDR Moved design and interface to separate documents. -# -# 2001-12-10 GDR Open cache file as binary on Windows. Allow -# simultaneous -e and -x, or -a and -r. -# -# 2001-12-12 GDR Added command-line help. Cache analysis so that it -# only needs to be done once when you specify -a and -r. -# -# 2001-12-13 GDR Improved speed while recording. Portable between -# Python 1.5.2 and 2.1.1. -# -# 2002-01-03 GDR Module-level functions work correctly. -# -# 2002-01-07 GDR Update sys.path when running a file with the -x option, -# so that it matches the value the program would get if it were run on -# its own. -# -# 2004-12-12 NMB Significant code changes. -# - Finding executable statements has been rewritten so that docstrings and -# other quirks of Python execution aren't mistakenly identified as missing -# lines. -# - Lines can be excluded from consideration, even entire suites of lines. -# - The filesystem cache of covered lines can be disabled programmatically. -# - Modernized the code. -# -# 2004-12-14 NMB Minor tweaks. Return 'analysis' to its original behavior -# and add 'analysis2'. Add a global for 'annotate', and factor it, adding -# 'annotate_file'. -# -# 2004-12-31 NMB Allow for keyword arguments in the module global functions. -# -# C. COPYRIGHT AND LICENCE -# -# Copyright 2001 Gareth Rees. All rights reserved. -# Copyright 2004 Ned Batchelder. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the -# distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -# DAMAGE. -# -# $Id: coverage.py 5 2004-12-14 12:08:23Z ned $ diff --git a/modules/ez_setup.py b/modules/ez_setup.py deleted file mode 100644 index f2fc782563c..00000000000 --- a/modules/ez_setup.py +++ /dev/null @@ -1,219 +0,0 @@ -#!python -"""Bootstrap setuptools installation - -If you want to use setuptools in your package's setup.py, just include this -file in the same directory with it, and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -If you want to require a specific version of setuptools, set a download -mirror, or use an alternate download directory, you can do so by supplying -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import sys -DEFAULT_VERSION = "0.6a8" -DEFAULT_URL = "http://cheeseshop.python.org/packages/%s/s/setuptools/" % sys.version[:3] - -md5_data = { - 'setuptools-0.5a13-py2.3.egg': '85edcf0ef39bab66e130d3f38f578c86', - 'setuptools-0.5a13-py2.4.egg': 'ede4be600e3890e06d4ee5e0148e092a', - 'setuptools-0.6a1-py2.3.egg': 'ee819a13b924d9696b0d6ca6d1c5833d', - 'setuptools-0.6a1-py2.4.egg': '8256b5f1cd9e348ea6877b5ddd56257d', - 'setuptools-0.6a2-py2.3.egg': 'b98da449da411267c37a738f0ab625ba', - 'setuptools-0.6a2-py2.4.egg': 'be5b88bc30aed63fdefd2683be135c3b', - 'setuptools-0.6a3-py2.3.egg': 'ee0e325de78f23aab79d33106dc2a8c8', - 'setuptools-0.6a3-py2.4.egg': 'd95453d525a456d6c23e7a5eea89a063', - 'setuptools-0.6a4-py2.3.egg': 'e958cbed4623bbf47dd1f268b99d7784', - 'setuptools-0.6a4-py2.4.egg': '7f33c3ac2ef1296f0ab4fac1de4767d8', - 'setuptools-0.6a5-py2.3.egg': '748408389c49bcd2d84f6ae0b01695b1', - 'setuptools-0.6a5-py2.4.egg': '999bacde623f4284bfb3ea77941d2627', - 'setuptools-0.6a6-py2.3.egg': '7858139f06ed0600b0d9383f36aca24c', - 'setuptools-0.6a6-py2.4.egg': 'c10d20d29acebce0dc76219dc578d058', - 'setuptools-0.6a7-py2.3.egg': 'cfc4125ddb95c07f9500adc5d6abef6f', - 'setuptools-0.6a7-py2.4.egg': 'c6d62dab4461f71aed943caea89e6f20', - 'setuptools-0.6a8-py2.3.egg': '2f18eaaa3f544f5543ead4a68f3b2e1a', - 'setuptools-0.6a8-py2.4.egg': '799018f2894f14c9f8bcb2b34e69b391', -} - -import sys, os - -def _validate_md5(egg_name, data): - if egg_name in md5_data: - from md5 import md5 - digest = md5(data).hexdigest() - if digest != md5_data[egg_name]: - print >>sys.stderr, ( - "md5 validation of %s failed! (Possible download problem?)" - % egg_name - ) - sys.exit(2) - return data - - -def use_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - download_delay=15 -): - """Automatically find/download setuptools and make it available on sys.path - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end with - a '/'). `to_dir` is the directory where setuptools will be downloaded, if - it is not already available. If `download_delay` is specified, it should - be the number of seconds that will be paused before initiating a download, - should one be required. If an older version of setuptools is installed, - this routine will print a message to ``sys.stderr`` and raise SystemExit in - an attempt to abort the calling script. - """ - try: - import setuptools - if setuptools.__version__ == '0.0.1': - print >>sys.stderr, ( - "You have an obsolete version of setuptools installed. Please\n" - "remove it from your system entirely before rerunning this script." - ) - sys.exit(2) - except ImportError: - egg = download_setuptools(version, download_base, to_dir, download_delay) - sys.path.insert(0, egg) - import setuptools; setuptools.bootstrap_install_from = egg - - import pkg_resources - try: - pkg_resources.require("setuptools>="+version) - - except pkg_resources.VersionConflict: - # XXX could we install in a subprocess here? - print >>sys.stderr, ( - "The required version of setuptools (>=%s) is not available, and\n" - "can't be installed while this script is running. Please install\n" - " a more recent version first." - ) % version - sys.exit(2) - -def download_setuptools( - version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, - delay = 15 -): - """Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an egg for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download attempt. - """ - import urllib2, shutil - egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3]) - url = download_base + egg_name - saveto = os.path.join(to_dir, egg_name) - src = dst = None - if not os.path.exists(saveto): # Avoid repeated downloads - try: - from distutils import log - if delay: - log.warn(""" ---------------------------------------------------------------------------- -This script requires setuptools version %s to run (even to display -help). I will attempt to download it for you (from -%s), but -you may need to enable firewall access for this script first. -I will start the download in %d seconds. ----------------------------------------------------------------------------""", - version, download_base, delay - ); from time import sleep; sleep(delay) - log.warn("Downloading %s", url) - src = urllib2.urlopen(url) - # Read/write all in one block, so we don't create a corrupt file - # if the download is interrupted. - data = _validate_md5(egg_name, src.read()) - dst = open(saveto,"wb"); dst.write(data) - finally: - if src: src.close() - if dst: dst.close() - return os.path.realpath(saveto) - -def main(argv, version=DEFAULT_VERSION): - """Install or upgrade setuptools and EasyInstall""" - - try: - import setuptools - except ImportError: - import tempfile, shutil - tmpdir = tempfile.mkdtemp(prefix="easy_install-") - try: - egg = download_setuptools(version, to_dir=tmpdir, delay=0) - sys.path.insert(0,egg) - from setuptools.command.easy_install import main - main(list(argv)+[egg]) - finally: - shutil.rmtree(tmpdir) - else: - if setuptools.__version__ == '0.0.1': - # tell the user to uninstall obsolete version - use_setuptools(version) - - req = "setuptools>="+version - import pkg_resources - try: - pkg_resources.require(req) - except pkg_resources.VersionConflict: - try: - from setuptools.command.easy_install import main - except ImportError: - from easy_install import main - main(list(argv)+[download_setuptools(delay=0)]) - sys.exit(0) # try to force an exit - else: - if argv: - from setuptools.command.easy_install import main - main(argv) - else: - print "Setuptools version",version,"or greater has been installed." - print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)' - - - -def update_md5(filenames): - """Update our built-in md5 registry""" - - import re - from md5 import md5 - - for name in filenames: - base = os.path.basename(name) - f = open(name,'rb') - md5_data[base] = md5(f.read()).hexdigest() - f.close() - - data = [" %r: %r,\n" % it for it in md5_data.items()] - data.sort() - repl = "".join(data) - - import inspect - srcfile = inspect.getsourcefile(sys.modules[__name__]) - f = open(srcfile, 'rb'); src = f.read(); f.close() - - match = re.search("\nmd5_data = {\n([^}]+)}", src) - if not match: - print >>sys.stderr, "Internal error!" - sys.exit(2) - - src = src[:match.start(1)] + repl + src[match.end(1):] - f = open(srcfile,'w') - f.write(src) - f.close() - - -if __name__=='__main__': - if len(sys.argv)>2 and sys.argv[1]=='--md5update': - update_md5(sys.argv[2:]) - else: - main(sys.argv[1:]) - - - - - diff --git a/modules/misc.py b/modules/misc.py deleted file mode 100644 index 5673dfa1b66..00000000000 --- a/modules/misc.py +++ /dev/null @@ -1,9 +0,0 @@ -import bz2, gzip - -def open_compressed( filename, mode='r' ): - if filename.endswith( ".bz2" ): - return bz2.BZ2File( filename, mode ) - elif filename.endswith( ".gz" ): - return gzip.GzipFile( filename, mode ) - else: - return file( filename, mode ) diff --git a/nosetests.sh b/nosetests.sh index 65d9aad70ec..1d9bd767694 100755 --- a/nosetests.sh +++ b/nosetests.sh @@ -17,4 +17,4 @@ export PYTHONPATH=$UNIVERSE_HOME/lib:$UNIVERSE_HOME/modules:$UNIVERSE_HOME/eggs: echo "python path: $PYTHONPATH" -python2.4 nosetests.py $@ +python2.4 ./scripts/nosetests.py $@ diff --git a/run.sh b/run.sh index f2df4d00abf..195a8aa9146 100644 --- a/run.sh +++ b/run.sh @@ -17,4 +17,4 @@ export PYTHONPATH=$UNIVERSE_HOME/lib:$UNIVERSE_HOME/modules:$UNIVERSE_HOME/eggs: echo "python path: $PYTHONPATH" -python2.4 paster.py serve universe_wsgi.ini $@ +python2.4 ./scripts/paster.py serve universe_wsgi.ini $@ diff --git a/nosetests.py b/scripts/nosetests.py similarity index 100% rename from nosetests.py rename to scripts/nosetests.py diff --git a/paster.py b/scripts/paster.py similarity index 100% rename from paster.py rename to scripts/paster.py diff --git a/modules/rst2html.py b/scripts/rst2html.py similarity index 100% rename from modules/rst2html.py rename to scripts/rst2html.py