diff options
author | Georg Brandl <georg@python.org> | 2014-09-30 20:51:30 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2014-09-30 20:51:30 (GMT) |
commit | 97e9ec688c7ea49c61c803f1c87b183e32b3661c (patch) | |
tree | 29c33fb8941b0a7f2c5053756af68c1c0aa22003 /Doc/tools/c_annotations.py | |
parent | 2b1a0a30c9468bcb855fb8b60faaedbf5495904b (diff) | |
download | cpython-97e9ec688c7ea49c61c803f1c87b183e32b3661c.zip cpython-97e9ec688c7ea49c61c803f1c87b183e32b3661c.tar.gz cpython-97e9ec688c7ea49c61c803f1c87b183e32b3661c.tar.bz2 |
Move Doc/tools/sphinxext content to Doc/tools, there is no need for the nested subdirectory anymore.
Diffstat (limited to 'Doc/tools/c_annotations.py')
-rw-r--r-- | Doc/tools/c_annotations.py | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/Doc/tools/c_annotations.py b/Doc/tools/c_annotations.py new file mode 100644 index 0000000..baa39f3 --- /dev/null +++ b/Doc/tools/c_annotations.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +""" + c_annotations.py + ~~~~~~~~~~~~~~~~ + + Supports annotations for C API elements: + + * reference count annotations for C API functions. Based on + refcount.py and anno-api.py in the old Python documentation tools. + + * stable API annotations + + Usage: Set the `refcount_file` config value to the path to the reference + count data file. + + :copyright: Copyright 2007-2014 by Georg Brandl. + :license: Python license. +""" + +from os import path +from docutils import nodes +from docutils.parsers.rst import directives + +from sphinx import addnodes +from sphinx.domains.c import CObject + + +class RCEntry: + def __init__(self, name): + self.name = name + self.args = [] + self.result_type = '' + self.result_refs = None + + +class Annotations(dict): + @classmethod + def fromfile(cls, filename): + d = cls() + fp = open(filename, 'r') + try: + for line in fp: + line = line.strip() + if line[:1] in ("", "#"): + # blank lines and comments + continue + parts = line.split(":", 4) + if len(parts) != 5: + raise ValueError("Wrong field count in %r" % line) + function, type, arg, refcount, comment = parts + # Get the entry, creating it if needed: + try: + entry = d[function] + except KeyError: + entry = d[function] = RCEntry(function) + if not refcount or refcount == "null": + refcount = None + else: + refcount = int(refcount) + # Update the entry with the new parameter or the result + # information. + if arg: + entry.args.append((arg, type, refcount)) + else: + entry.result_type = type + entry.result_refs = refcount + finally: + fp.close() + return d + + def add_annotations(self, app, doctree): + for node in doctree.traverse(addnodes.desc_content): + par = node.parent + if par['domain'] != 'c': + continue + if par['stableabi']: + node.insert(0, nodes.emphasis(' Part of the stable ABI.', + ' Part of the stable ABI.', + classes=['stableabi'])) + if par['objtype'] != 'function': + continue + if not par[0].has_key('names') or not par[0]['names']: + continue + name = par[0]['names'][0] + if name.startswith("c."): + name = name[2:] + entry = self.get(name) + if not entry: + continue + elif entry.result_type not in ("PyObject*", "PyVarObject*"): + continue + if entry.result_refs is None: + rc = 'Return value: Always NULL.' + elif entry.result_refs: + rc = 'Return value: New reference.' + else: + rc = 'Return value: Borrowed reference.' + node.insert(0, nodes.emphasis(rc, rc, classes=['refcount'])) + + +def init_annotations(app): + refcounts = Annotations.fromfile( + path.join(app.srcdir, app.config.refcount_file)) + app.connect('doctree-read', refcounts.add_annotations) + + +def setup(app): + app.add_config_value('refcount_file', '', True) + app.connect('builder-inited', init_annotations) + + # monkey-patch C object... + CObject.option_spec = { + 'noindex': directives.flag, + 'stableabi': directives.flag, + } + old_handle_signature = CObject.handle_signature + def new_handle_signature(self, sig, signode): + signode.parent['stableabi'] = 'stableabi' in self.options + return old_handle_signature(self, sig, signode) + CObject.handle_signature = new_handle_signature + return {'version': '1.0', 'parallel_read_safe': True} |