From b4e73a73538a6687ed6e3c407839c86fdf69affb Mon Sep 17 00:00:00 2001 From: Ben Darnell Date: Fri, 11 Nov 2011 20:35:26 -0800 Subject: [PATCH] Local copy of sphix coverage plugin is no longer needed in version 1.1 --- website/sphinx/conf.py | 6 +- website/sphinx/sphinx_coverage.py | 264 ------------------------------ 2 files changed, 1 insertion(+), 269 deletions(-) delete mode 100644 website/sphinx/sphinx_coverage.py diff --git a/website/sphinx/conf.py b/website/sphinx/conf.py index 905ab410..036fb411 100644 --- a/website/sphinx/conf.py +++ b/website/sphinx/conf.py @@ -4,10 +4,6 @@ import sys sys.path.insert(0, os.path.abspath("../..")) import tornado -# For our version of sphinx_coverage.py. The version in sphinx 1.0.7 -# has too many false positives; this version comes from upstream HG. -sys.path.append(os.path.abspath(".")) - master_doc = "index" project = "Tornado" @@ -15,7 +11,7 @@ copyright = "2011, Facebook" version = release = tornado.version -extensions = ["sphinx.ext.autodoc", "sphinx_coverage", "sphinx.ext.viewcode"] +extensions = ["sphinx.ext.autodoc", "sphinx.ext.coverage", "sphinx.ext.viewcode"] primary_domain = 'py' default_role = 'py:obj' diff --git a/website/sphinx/sphinx_coverage.py b/website/sphinx/sphinx_coverage.py deleted file mode 100644 index 5ff81d70..00000000 --- a/website/sphinx/sphinx_coverage.py +++ /dev/null @@ -1,264 +0,0 @@ -# -*- coding: utf-8 -*- -""" - sphinx.ext.coverage - ~~~~~~~~~~~~~~~~~~~ - - Check Python modules and C API for coverage. Mostly written by Josip - Dzolonga for the Google Highly Open Participation contest. - - :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import re -import glob -import inspect -import cPickle as pickle -from os import path - -from sphinx.builders import Builder - - -# utility -def write_header(f, text, char='-'): - f.write(text + '\n') - f.write(char * len(text) + '\n') - -def compile_regex_list(name, exps, warnfunc): - lst = [] - for exp in exps: - try: - lst.append(re.compile(exp)) - except Exception: - warnfunc('invalid regex %r in %s' % (exp, name)) - return lst - - -class CoverageBuilder(Builder): - - name = 'coverage' - - def init(self): - self.c_sourcefiles = [] - for pattern in self.config.coverage_c_path: - pattern = path.join(self.srcdir, pattern) - self.c_sourcefiles.extend(glob.glob(pattern)) - - self.c_regexes = [] - for (name, exp) in self.config.coverage_c_regexes.items(): - try: - self.c_regexes.append((name, re.compile(exp))) - except Exception: - self.warn('invalid regex %r in coverage_c_regexes' % exp) - - self.c_ignorexps = {} - for (name, exps) in self.config.coverage_ignore_c_items.iteritems(): - self.c_ignorexps[name] = compile_regex_list( - 'coverage_ignore_c_items', exps, self.warn) - self.mod_ignorexps = compile_regex_list( - 'coverage_ignore_modules', self.config.coverage_ignore_modules, - self.warn) - self.cls_ignorexps = compile_regex_list( - 'coverage_ignore_classes', self.config.coverage_ignore_classes, - self.warn) - self.fun_ignorexps = compile_regex_list( - 'coverage_ignore_functions', self.config.coverage_ignore_functions, - self.warn) - - def get_outdated_docs(self): - return 'coverage overview' - - def write(self, *ignored): - self.py_undoc = {} - self.build_py_coverage() - self.write_py_coverage() - - self.c_undoc = {} - self.build_c_coverage() - self.write_c_coverage() - - def build_c_coverage(self): - # Fetch all the info from the header files - c_objects = self.env.domaindata['c']['objects'] - for filename in self.c_sourcefiles: - undoc = [] - f = open(filename, 'r') - try: - for line in f: - for key, regex in self.c_regexes: - match = regex.match(line) - if match: - name = match.groups()[0] - if name not in c_objects: - for exp in self.c_ignorexps.get(key, ()): - if exp.match(name): - break - else: - undoc.append((key, name)) - continue - finally: - f.close() - if undoc: - self.c_undoc[filename] = undoc - - def write_c_coverage(self): - output_file = path.join(self.outdir, 'c.txt') - op = open(output_file, 'w') - try: - if self.config.coverage_write_headline: - write_header(op, 'Undocumented C API elements', '=') - op.write('\n') - - for filename, undoc in self.c_undoc.iteritems(): - write_header(op, filename) - for typ, name in undoc: - op.write(' * %-50s [%9s]\n' % (name, typ)) - op.write('\n') - finally: - op.close() - - def build_py_coverage(self): - objects = self.env.domaindata['py']['objects'] - modules = self.env.domaindata['py']['modules'] - - skip_undoc = self.config.coverage_skip_undoc_in_source - - for mod_name in modules: - ignore = False - for exp in self.mod_ignorexps: - if exp.match(mod_name): - ignore = True - break - if ignore: - continue - - try: - mod = __import__(mod_name, fromlist=['foo']) - except ImportError, err: - self.warn('module %s could not be imported: %s' % - (mod_name, err)) - self.py_undoc[mod_name] = {'error': err} - continue - - funcs = [] - classes = {} - - for name, obj in inspect.getmembers(mod): - # diverse module attributes are ignored: - if name[0] == '_': - # begins in an underscore - continue - if not hasattr(obj, '__module__'): - # cannot be attributed to a module - continue - if obj.__module__ != mod_name: - # is not defined in this module - continue - - full_name = '%s.%s' % (mod_name, name) - - if inspect.isfunction(obj): - if full_name not in objects: - for exp in self.fun_ignorexps: - if exp.match(name): - break - else: - if skip_undoc and not obj.__doc__: - continue - funcs.append(name) - elif inspect.isclass(obj): - for exp in self.cls_ignorexps: - if exp.match(name): - break - else: - if full_name not in objects: - if skip_undoc and not obj.__doc__: - continue - # not documented at all - classes[name] = [] - continue - - attrs = [] - - for attr_name in dir(obj): - if attr_name not in obj.__dict__: - continue - attr = getattr(obj, attr_name) - if not (inspect.ismethod(attr) or - inspect.isfunction(attr)): - continue - if attr_name[0] == '_': - # starts with an underscore, ignore it - continue - if skip_undoc and not attr.__doc__: - # skip methods without docstring if wished - continue - - full_attr_name = '%s.%s' % (full_name, attr_name) - if full_attr_name not in objects: - attrs.append(attr_name) - - if attrs: - # some attributes are undocumented - classes[name] = attrs - - self.py_undoc[mod_name] = {'funcs': funcs, 'classes': classes} - - def write_py_coverage(self): - output_file = path.join(self.outdir, 'python.txt') - op = open(output_file, 'w') - failed = [] - try: - if self.config.coverage_write_headline: - write_header(op, 'Undocumented Python objects', '=') - keys = self.py_undoc.keys() - keys.sort() - for name in keys: - undoc = self.py_undoc[name] - if 'error' in undoc: - failed.append((name, undoc['error'])) - else: - if not undoc['classes'] and not undoc['funcs']: - continue - - write_header(op, name) - if undoc['funcs']: - op.write('Functions:\n') - op.writelines(' * %s\n' % x for x in undoc['funcs']) - op.write('\n') - if undoc['classes']: - op.write('Classes:\n') - for name, methods in sorted(undoc['classes'].iteritems()): - if not methods: - op.write(' * %s\n' % name) - else: - op.write(' * %s -- missing methods:\n' % name) - op.writelines(' - %s\n' % x for x in methods) - op.write('\n') - - if failed: - write_header(op, 'Modules that failed to import') - op.writelines(' * %s -- %s\n' % x for x in failed) - finally: - op.close() - - def finish(self): - # dump the coverage data to a pickle file too - picklepath = path.join(self.outdir, 'undoc.pickle') - dumpfile = open(picklepath, 'wb') - try: - pickle.dump((self.py_undoc, self.c_undoc), dumpfile) - finally: - dumpfile.close() - - -def setup(app): - app.add_builder(CoverageBuilder) - app.add_config_value('coverage_ignore_modules', [], False) - app.add_config_value('coverage_ignore_functions', [], False) - app.add_config_value('coverage_ignore_classes', [], False) - app.add_config_value('coverage_c_path', [], False) - app.add_config_value('coverage_c_regexes', {}, False) - app.add_config_value('coverage_ignore_c_items', {}, False) - app.add_config_value('coverage_write_headline', True, False) - app.add_config_value('coverage_skip_undoc_in_source', False, False)