Skip to content

Commit

Permalink
DOC add links to github sourcecode in API reference
Browse files Browse the repository at this point in the history
  • Loading branch information
jnothman committed Jul 21, 2014
1 parent e79d2bb commit 06b57ae
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ test-code: in
test-sphinxext:
$(NOSETESTS) -s -v doc/sphinxext/
test-doc:
$(NOSETESTS) -s -v doc/ doc/modules/ doc/datasets/ \
$(NOSETESTS) -s -v doc/*.rst doc/modules/ doc/datasets/ \
doc/developers doc/tutorial/basic doc/tutorial/statistical_inference \
doc/tutorial/text_analytics

Expand Down
13 changes: 12 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# All configuration values have a default; values that are commented out
# serve to show the default.

from __future__ import print_function
import sys
import os
from sklearn.externals.six import u
Expand All @@ -22,6 +23,8 @@
# absolute, like shown here.
sys.path.insert(0, os.path.abspath('sphinxext'))

from github_link import make_linkcode_resolve

# -- General configuration ---------------------------------------------------

# Try to override the matplotlib configuration as early as possible
Expand All @@ -34,7 +37,8 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['gen_rst',
'sphinx.ext.autodoc', 'sphinx.ext.autosummary',
'sphinx.ext.pngmath', 'numpy_ext.numpydoc'
'sphinx.ext.pngmath', 'numpy_ext.numpydoc',
'sphinx.ext.linkcode',
]

autosummary_generate = True
Expand Down Expand Up @@ -231,3 +235,10 @@ def setup(app):
app.add_javascript('js/copybutton.js')
# to format example galleries:
app.add_javascript('js/examples.js')


# The following is used by sphinx.ext.linkcode to provide links to github
linkcode_resolve = make_linkcode_resolve('sklearn',
u'https://github.com/scikit-learn/'
'scikit-learn/blob/{revision}/'
'{package}/{path}#L{lineno}')
84 changes: 84 additions & 0 deletions doc/sphinxext/github_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from operator import attrgetter
import inspect
import subprocess
import os
import sys
from functools import partial

REVISION_CMD = 'git rev-parse --short HEAD'


def _get_git_revision():
try:
revision = subprocess.check_output(REVISION_CMD.split()).strip()
except subprocess.CalledProcessError:
print('Failed to execute git to get revision')
return None
return revision.decode('utf-8')


def _linkcode_resolve(domain, info, package, url_fmt, revision):
"""Determine a link to online source for a class/method/function
This is called by sphinx.ext.linkcode
An example with a long-untouched module that everyone has
>>> _linkcode_resolve('py', {'module': 'tty',
... 'fullname': 'setraw'},
... package='tty',
... url_fmt='http://hg.python.org/cpython/file/'
... '{revision}/Lib/{package}/{path}#L{lineno}',
... revision='xxxx')
'http://hg.python.org/cpython/file/xxxx/Lib/tty/tty.py#L18'
"""

if revision is None:
return
if domain not in ('py', 'pyx'):
return
if not info.get('module') or not info.get('fullname'):
return

class_name = info['fullname'].split('.')[0]
if type(class_name) != str:
# Python 2 only
class_name = class_name.encode('utf-8')
module = __import__(info['module'], fromlist=[class_name])
obj = attrgetter(info['fullname'])(module)

try:
fn = inspect.getsourcefile(obj)
except Exception:
fn = None
if not fn:
try:
fn = inspect.getsourcefile(sys.modules[obj.__module__])
except Exception:
fn = None
if not fn:
return

fn = os.path.relpath(fn,
start=os.path.dirname(__import__(package).__file__))
try:
lineno = inspect.getsourcelines(obj)[1]
except Exception:
lineno = ''
return url_fmt.format(revision=revision, package=package,
path=fn, lineno=lineno)


def make_linkcode_resolve(package, url_fmt):
"""Returns a linkcode_resolve function for the given URL format
revision is a git commit reference (hash or name)
package is the name of the root module of the package
url_fmt is along the lines of ('https://github.com/USER/PROJECT/'
'blob/{revision}/{package}/'
'{path}#L{lineno}')
"""
revision = _get_git_revision()
return partial(_linkcode_resolve, revision=revision, package=package,
url_fmt=url_fmt)

0 comments on commit 06b57ae

Please sign in to comment.