# -*- coding: utf-8 -*-""" sphinx.ext.refcounting ~~~~~~~~~~~~~~~~~~~~~~ Supports reference count annotations for C API functions. Based on refcount.py and anno-api.py in the old Python documentation tools. Usage: Set the `refcount_file` config value to the path to the reference count data file. :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details."""fromosimportpathfromdocutilsimportnodesfromsphinximportaddnodesfromsphinx.localeimport_# refcount annotationclassrefcount(nodes.emphasis):passclassRCEntry:def__init__(self,name):self.name=nameself.args=[]self.result_type=''self.result_refs=NoneclassRefcounts(dict):@classmethoddeffromfile(cls,filename):d=cls()fp=open(filename,'r')try:forlineinfp:line=line.strip()ifline[:1]in("","#"):# blank lines and commentscontinueparts=line.split(":",4)iflen(parts)!=5:raiseValueError("Wrong field count in %r"%line)function,type,arg,refcount,comment=parts# Get the entry, creating it if needed:try:entry=d[function]exceptKeyError:entry=d[function]=RCEntry(function)ifnotrefcountorrefcount=="null":refcount=Noneelse:refcount=int(refcount)# Update the entry with the new parameter or the result# information.ifarg:entry.args.append((arg,type,refcount))else:entry.result_type=typeentry.result_refs=refcountfinally:fp.close()returnddefadd_refcount_annotations(self,app,doctree):fornodeindoctree.traverse(addnodes.desc_content):par=node.parentifpar['domain']!='c'orpar['objtype']!='function':continueifnotpar[0].has_key('names')ornotpar[0]['names']:continueentry=self.get(par[0]['names'][0])ifnotentry:continueelifentry.result_typenotin("PyObject*","PyVarObject*"):continuerc=_('Return value: ')ifentry.result_refsisNone:rc+=_("Always NULL.")else:ifentry.result_refs:rc+=_("New reference.")else:rc+=_("Borrowed reference.")node.insert(0,refcount(rc,rc))definit_refcounts(app):ifapp.config.refcount_file:refcounts=Refcounts.fromfile(path.join(app.srcdir,app.config.refcount_file))app.connect('doctree-read',refcounts.add_refcount_annotations)defsetup(app):app.add_node(refcount)app.add_config_value('refcount_file','',True)app.connect('builder-inited',init_refcounts)