diff options
author | Robert Lehmann <mail@robertlehmann.de> | 2011-10-08 14:09:21 +0200 |
---|---|---|
committer | Robert Lehmann <mail@robertlehmann.de> | 2011-10-08 14:09:21 +0200 |
commit | c89bfd9ec0cda23d50505551c5468ebc6d24bb6c (patch) | |
tree | 478f7deb1fd7275ffb77884a82de0be51a3ead0b | |
parent | f81ceba276d562a24d2765d85e73c165d5d38499 (diff) | |
parent | 65ae0fd07a7279c4a6b6b058541fcc5beb70e039 (diff) | |
download | sphinx-c89bfd9ec0cda23d50505551c5468ebc6d24bb6c.tar.gz |
merge
-rw-r--r-- | CHANGES | 2 | ||||
-rw-r--r-- | sphinx/apidoc.py | 101 | ||||
-rw-r--r-- | sphinx/pycode/__init__.py | 1 |
3 files changed, 54 insertions, 50 deletions
@@ -121,6 +121,8 @@ Release 1.0.9 (in development) * #778: Fix "hide search matches" link on pages linked by search. +* Fix the source positions referenced by the "viewcode" extension. + Release 1.0.8 (Sep 23, 2011) ============================ diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index 5b6163dd..24c56fbf 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -28,6 +28,7 @@ OPTIONS = [ INITPY = '__init__.py' + def makename(package, module): """Join package and module with a dot.""" # Both package and module can be None/empty. @@ -39,6 +40,7 @@ def makename(package, module): name = module return name + def write_file(name, text, opts): """Write the output file for module/package <name>.""" fname = path.join(opts.destdir, '%s.%s' % (name, opts.suffix)) @@ -55,11 +57,13 @@ def write_file(name, text, opts): finally: f.close() + def format_heading(level, text): """Create a heading of <level> [1, 2 or 3 supported].""" underlining = ['=', '-', '~', ][level-1] * len(text) return '%s\n%s\n\n' % (text, underlining) + def format_directive(module, package=None): """Create the automodule directive and add the options.""" directive = '.. automodule:: %s\n' % makename(package, module) @@ -67,6 +71,7 @@ def format_directive(module, package=None): directive += ' :%s:\n' % option return directive + def create_module_file(package, module, opts): """Build the text of the file and write the file.""" text = format_heading(1, '%s Module' % module) @@ -74,6 +79,7 @@ def create_module_file(package, module, opts): text += format_directive(module, package) write_file(makename(package, module), text, opts) + def create_package_file(root, master_package, subroot, py_files, opts, subs): """Build the text of the file and write the file.""" package = path.split(root)[-1] @@ -106,10 +112,9 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs): write_file(makename(master_package, subroot), text, opts) + def create_modules_toc_file(modules, opts, name='modules'): - """ - Create the module's index. - """ + """Create the module's index.""" text = format_heading(1, '%s' % opts.header) text += '.. toctree::\n' text += ' :maxdepth: %s\n\n' % opts.maxdepth @@ -125,12 +130,12 @@ def create_modules_toc_file(modules, opts, name='modules'): write_file(name, text, opts) + def shall_skip(module): - """ - Check if we want to skip this module. - """ - # skip it, if there is nothing (or just \n or \r\n) in the file - return path.getsize(module) < 3 + """Check if we want to skip this module.""" + # skip it if there is nothing (or just \n or \r\n) in the file + return path.getsize(module) <= 2 + def recurse_tree(rootpath, excludes, opts): """ @@ -139,54 +144,50 @@ def recurse_tree(rootpath, excludes, opts): """ # use absolute path for root, as relative paths like '../../foo' cause # 'if "/." in root ...' to filter out *all* modules otherwise - rootpath = os.path.abspath(rootpath) - # check if the base directory is a package and get is name + rootpath = path.normpath(path.abspath(rootpath)) + # check if the base directory is a package and get its name if INITPY in os.listdir(rootpath): - package_name = rootpath.split(path.sep)[-1] + root_package = rootpath.split(path.sep)[-1] else: - package_name = None - - toc = [] - tree = os.walk(rootpath, False) - for root, subs, files in tree: - # keep only the Python script files - py_files = sorted([f for f in files if path.splitext(f)[1] == '.py']) - if INITPY in py_files: + # otherwise, the base is a directory with packages + root_package = None + + toplevels = [] + for root, subs, files in os.walk(rootpath): + if is_excluded(root, excludes): + del subs[:] + continue + # document only Python module files + py_files = sorted([f for f in files if path.splitext(f)[1] == '.py']) + is_pkg = INITPY in py_files + if is_pkg: py_files.remove(INITPY) py_files.insert(0, INITPY) - # remove hidden ('.') and private ('_') directories - subs = sorted([sub for sub in subs if sub[0] not in ['.', '_']]) - # check if there are valid files to process - # TODO: could add check for windows hidden files - if "/." in root or "/_" in root \ - or not py_files \ - or is_excluded(root, excludes): + elif root != rootpath: + # only accept non-package at toplevel + del subs[:] continue - if INITPY in py_files: - # we are in package ... - if (# ... with subpackage(s) - subs - or - # ... with some module(s) - len(py_files) > 1 - or - # ... with a not-to-be-skipped INITPY file - not shall_skip(path.join(root, INITPY)) - ): - subroot = root[len(rootpath):].lstrip(path.sep).\ - replace(path.sep, '.') - create_package_file(root, package_name, subroot, + # remove hidden ('.') and private ('_') directories + subs[:] = sorted(sub for sub in subs if sub[0] not in ['.', '_']) + + if is_pkg: + # we are in a package with something to document + if subs or len(py_files) > 1 or not shall_skip(path.join(root, INITPY)): + subpackage = root[len(rootpath):].lstrip(path.sep).\ + replace(path.sep, '.') + create_package_file(root, root_package, subpackage, py_files, opts, subs) - toc.append(makename(package_name, subroot)) - elif root == rootpath: + toplevels.append(makename(root_package, subpackage)) + else: # if we are at the root level, we don't require it to be a package + assert root == rootpath and root_package is None for py_file in py_files: if not shall_skip(path.join(rootpath, py_file)): module = path.splitext(py_file)[0] - create_module_file(package_name, module, opts) - toc.append(makename(package_name, module)) + create_module_file(root_package, module, opts) + toplevels.append(module) - return toc + return toplevels def normalize_excludes(rootpath, excludes): @@ -196,16 +197,14 @@ def normalize_excludes(rootpath, excludes): * otherwise it is joined with rootpath * with trailing slash """ - sep = path.sep f_excludes = [] for exclude in excludes: if not path.isabs(exclude) and not exclude.startswith(rootpath): exclude = path.join(rootpath, exclude) - if not exclude.endswith(sep): - exclude += sep - f_excludes.append(exclude) + f_excludes.append(path.normpath(exclude) + path.sep) return f_excludes + def is_excluded(root, excludes): """ Check if the directory is in the exclude list. @@ -221,6 +220,7 @@ def is_excluded(root, excludes): return True return False + def main(argv=sys.argv): """ Parse and check the command line arguments. @@ -268,7 +268,7 @@ Note: By default this script will not overwrite already created files.""") if not opts.destdir: parser.error('An output directory is required.') if opts.header is None: - opts.header = rootpath + opts.header = path.normpath(rootpath).split(path.sep)[-1] if opts.suffix.startswith('.'): opts.suffix = opts.suffix[1:] if not path.isdir(rootpath): @@ -301,6 +301,7 @@ Note: By default this script will not overwrite already created files.""") master = 'index', epub = True, ext_autodoc = True, + ext_viewcode = True, makefile = True, batchfile = True, mastertocmaxdepth = opts.maxdepth, diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index ac840750..09f7e220 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -217,6 +217,7 @@ class ModuleAnalyzer(object): pos = self.source.tell() if not decoded: self.encoding = detect_encoding(self.source.readline) + self.source.seek(pos) self.code = self.source.read().decode(self.encoding) self.source.seek(pos) self.source = TextIOWrapper(self.source, self.encoding) |