docs/conf.py
import importlib
import inspect
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# setup Django using django-configurations
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_app.settings")
os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')
# Fix Django's FileFields
from django.db.models.fields.files import FileDescriptor
FileDescriptor.__get__ = lambda self, *args, **kwargs: self
from django.db.models.manager import AbstractManagerDescriptor, ManagerDescriptor
ManagerDescriptor.__get__ = lambda self, *args, **kwargs: self.manager
AbstractManagerDescriptor.__get__ = lambda self, *args, **kwargs: None
# Stop Django from executing DB queries
from django.db.models.query import QuerySet
QuerySet.__repr__ = lambda self: self.__class__.__name__
try:
import enchant # NoQA
except ImportError:
enchant = None
GITHUB_USER = '' # Name of your Github user or organisation
GITHUB_PROJECT = '' # Name of your Github repository
def process_django_models(app, what, name, obj, options, lines):
"""Append params from fields to model documentation."""
from django.utils.encoding import force_text
from django.utils.html import strip_tags
from django.db import models
spelling_white_list = ['', '.. spelling::']
if inspect.isclass(obj) and issubclass(obj, models.Model):
for field in obj._meta.fields:
help_text = strip_tags(force_text(field.help_text))
verbose_name = force_text(field.verbose_name).capitalize()
if help_text:
lines.append(':param %s: %s - %s' % (field.attname, verbose_name, help_text))
else:
lines.append(':param %s: %s' % (field.attname, verbose_name))
if enchant is not None:
from enchant.tokenize import basic_tokenize
words = verbose_name.replace('-', '.').replace('_', '.').split('.')
words = [s for s in words if s != '']
for word in words:
spelling_white_list += [" %s" % ''.join(i for i in word if not i.isdigit())]
spelling_white_list += [" %s" % w[0] for w in basic_tokenize(word)]
field_type = type(field)
module = field_type.__module__
if 'django.db.models' in module:
# scope with django.db.models * imports
module = 'django.db.models'
lines.append(':type %s: %s.%s' % (field.attname, module, field_type.__name__))
if enchant is not None:
lines += spelling_white_list
return lines
def process_modules(app, what, name, obj, options, lines):
"""Add module names to spelling white list."""
if what != 'module':
return lines
from enchant.tokenize import basic_tokenize
spelling_white_list = ['', '.. spelling::']
words = name.replace('-', '.').replace('_', '.').split('.')
words = [s for s in words if s != '']
for word in words:
spelling_white_list += [" %s" % ''.join(i for i in word if not i.isdigit())]
spelling_white_list += [" %s" % w[0] for w in basic_tokenize(word)]
lines += spelling_white_list
return lines
def skip_queryset(app, what, name, obj, skip, options):
"""Skip queryset subclasses to avoid database queries."""
from django.db import models
if isinstance(obj, (models.QuerySet, models.manager.BaseManager)) or name.endswith('objects'):
return True
return skip
def setup(app):
# Register the docstring processor with sphinx
app.connect('autodoc-process-docstring', process_django_models)
app.connect('autodoc-skip-member', skip_queryset)
if enchant is not None:
app.connect('autodoc-process-docstring', process_modules)
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.graphviz',
'sphinx.ext.napoleon',
'sphinx.ext.linkcode',
'sphinx.ext.inheritance_diagram',
'sphinx.ext.intersphinx',
'configurations',
]
if enchant is not None:
extensions.append('sphinxcontrib.spelling')
intersphinx_mapping = {
'python': ('https://docs.python.org/3.5', None),
'sphinx': ('http://sphinx.pocoo.org/', None),
'django': ('https://docs.djangoproject.com/en/dev/', 'https://docs.djangoproject.com/en/dev/_objects/'),
'djangoextensions': ('https://django-extensions.readthedocs.org/en/latest/', None),
'geoposition': ('https://django-geoposition.readthedocs.org/en/latest/', None),
'braces': ('https://django-braces.readthedocs.org/en/latest/', None),
'select2': ('https://django-select2.readthedocs.org/en/latest/', None),
'celery': ('https://celery.readthedocs.org/en/latest/', None),
}
def linkcode_resolve(domain, info):
"""Link source code to GitHub."""
project = GITHUB_PROJECT
github_user = GITHUB_USER
head = 'master'
if domain != 'py' or not info['module']:
return None
filename = info['module'].replace('.', '/')
mod = importlib.import_module(info['module'])
basename = os.path.splitext(mod.__file__)[0]
if basename.endswith('__init__'):
filename += '/__init__'
item = mod
lineno = ''
for piece in info['fullname'].split('.'):
item = getattr(item, piece)
try:
lineno = '#L%d' % inspect.getsourcelines(item)[1]
except (TypeError, IOError):
pass
return ("https://github.com/%s/%s/blob/%s/%s.py%s" %
(github_user, project, head, filename, lineno))
autodoc_default_flags = ['members']
# spell checking
spelling_lang = 'en_US'
spelling_word_list_filename = 'spelling_wordlist.txt'
spelling_show_suggestions = True
spelling_ignore_pypi_package_names = True
# Here goes all your other config.
To test your docs, simply run the following test command:
(cd docs; make apidoc spelling)
To make fetch all the warnings in your test, simply add the -W
arguement in your docs Makefile
.
spelling:
$(SPHINXBUILD) -b spelling -W $(ALLSPHINXOPTS) $(BUILDDIR)/spelling
To make all this work on travis-ci you'll need to add the enchant binaries to the build. You won't need them on the deploy tho, since enchant is an optional import.
language: python
sudo: false
cache:
apt: true
pip: true
python:
- '3.5.1'
addons:
apt:
packages:
- python3-enchant
- graphviz