Skip to content
Create a gist now

Instantly share code, notes, and snippets.

python script to parse sphinx objects.inv file
#!/usr/bin/env python
""" Process URL for intersphinx targets and emit html or text """
def validuri(string):
return string
from sphinx.ext.intersphinx import read_inventory_v2
from posixpath import join
import pprint
import argparse
import locale
import os,sys,tempfile
import urllib2
parser = argparse.ArgumentParser(description='Process intersphinx link library')
parser.add_argument('--url' , type=validuri, help="URL to retrieve objects.inv from")
parser.add_argument('--file' , help="objects.inv format file")
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--html', action='store_true', help="Output HTML")
group.add_argument('--terse', action='store_true', help="Output terse text list")
group.add_argument('--rst', action='store_true', help="Output ReStructuredText")
group.add_argument('--rewrite', action='store_true', help="Output short form and correct form of each link.")
args = parser.parse_args()
def start_role(role):
if (args.terse):
elif (args.rewrite):
elif (args.rst):
print role
print "<dt>Role: {}</dt>\n<dd>\n<dl>\n".format(role)
def start_item(role,item):
if (args.terse):
elif (args.rewrite):
elif (args.rst):
print "\t:{}:{}:".format(role,item)
elif (args.html):
print "<dt>{}:{}</dt>\n".format(role,item)
print "<dd>"
print "<table>\n<tbody>"
def end_item(role,item):
if (args.html):
print "</tbody></table>"
print "</dd>\n"
def print_link(role,item,domain,title):
"""Return the correct link form, if no title then extended form."""
domain = domain.lower()
if (title == '')|(title=='-'):
linkStr = ":{}:`{} <{}:{}>`".format(role,item,domain,item)
linkStr = ":{}:`{}:{}`".format(role,domain,item)
if (args.terse):
print linkStr
if (args.rewrite):
print ":{}:`{}:{}`".format(role,domain,item), "\t{}".format(linkStr)
elif (args.rst):
print "\t\t:Link:\t{}".format(linkStr)
elif (args.html):
print "<tr><th>Link:</th><td>{}</td></tr>".format(linkStr)
def end_role():
if (args.html):
print "</dl>\n"
print "</dd>\n"
def print_meta(role,item,domain,version,url,title):
if (args.terse):
elif (args.rewrite):
elif (args.rst):
print "\t\t:Domain:\t{}".format(domain)
print "\t\t:Version:\t{}".format(version)
print "\t\t:URL:\t{}".format(url)
print "\t\t:Title:\t{}".format(title)
elif (args.html):
print "<tr><th>Domain:</th><td>{}</td></tr>".format(domain)
print "<tr><th>Version:</th><td>{}</td></tr>".format(version)
print "<tr><th>URL:</th><td>{}</td></tr>".format(url)
print "<tr><th>Title:</th><td>{}</td></tr>".format(title)
def fetch_data(url,inv):
f = open(inv, 'rb')
line = f.readline() # burn a line
invdata = read_inventory_v2(f, url, join)
if (args.html):
print "<dl>"
for role in invdata:
for item in invdata[role]:
(domain, version, url, title) = invdata[role][item]
#sys.stderr.write("{}:{} :: {}\n".format(role,item,invdata[role][item]))
if (args.html):
print "</dl>\n"
if __name__ == "__main__":
if (args.file):
inv = args.file
# if os.path.exists(inv) == False:
# raise Exception('File "{}" does not exist'.format(inv))
inv = False
if (args.url):
url = args.url
url = False
# sys.stderr.write('URL({}) FN({})\n'.format(url,fn))
if (inv == False) & (url == False):
raise Exception("need to specify a file or URL")
if (inv != False ) & (url != ''):
#sys.stderr.write("Reading from: {}\n".format(inv))
#sys.stderr.write("Using: {} as base HREF\n".format(url))
elif (url != False):
# fetch URL into inv
#sys.stderr.write("Retrieving objects.inv from {}\n".format(url))
if (url.rfind('objects.inv')>5):
invdata = urllib2.urlopen(url)
invdata = urllib2.urlopen(url + '/objects.inv')
sys.stderr.write('URL resolved to: {}\n '.format(invdata.geturl()))
f = tempfile.NamedTemporaryFile()
sys.stderr.write("objects.inv written to: {}\n".format(
sys.stderr.write("Using: {} as base HREF\n".format(url))
raise Exception("You need to specify a --URL")
lebigot commented Apr 8, 2014

This looks useful, but for me python --file objects.inv fails with:

Traceback (most recent call last):
  File "", line 139, in <module>
  File "", line 102, in fetch_data
    invdata = read_inventory_v2(f, url, join)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sphinx/ext/", line 118, in read_inventory_v2
    location = join(uri, location)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 77, in join
    elif path == '' or path.endswith('/'):
AttributeError: 'bool' object has no attribute 'endswith'
gmr commented Apr 28, 2014

There's a small fix in my fork of this, change line 102 from:

invdata = read_inventory_v2(f, url, join)


invdata = read_inventory_v2(f, url or '', join)
mearns commented May 19, 2014

I was getting weird permission errors trying to read the tempfile. Instead of debugging it, I just forked it and replaced the tempfile with a StringIO buffer. Also added a --output file, because in some cases I get a weird error trying to redirect the output.

Actually, my fork is of "gmr"'s fork, in case you're looking for it.

epc commented Mar 26, 2015

Slowest delayed reply ever: apologies for not seeing these comments last year, I didn't receive any notifications.

yoavram commented Oct 7, 2015

Also on Windows it fails, you should change from posixos import join to from os.path import join

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.