- uses sphinx-simple-theme
- uses some Mozilla specific styles and fonts
- splits the requirements files
- contains a Sphinx extension to automatically add parameters to model and form class docstrings for autodoc to find
- contains a Sphinx extension to make sure Celery tasks are automatically documented by autodoc
This commit is contained in:
Jannis Leidel 2017-06-08 17:50:35 +02:00 коммит произвёл Rob Hudson
Родитель 4200fbcc9f
Коммит 54ebfd5c57
52 изменённых файлов: 734 добавлений и 107 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -21,4 +21,4 @@ celerybeat.pid
celerymonitor.pid
.psql_history
.python_history
.config/configstore/update-notifier-npm.json
.config/

Просмотреть файл

@ -1,4 +1,6 @@
search: False
label_prs: update
requirements:
- requirements.txt
- requirements/build.txt
- requirements/docs.txt
- requirements/tests.txt

Просмотреть файл

@ -33,10 +33,10 @@ RUN mkdir -p /opt/npm /opt/static && \
chown -R 10001:10001 /opt
# Install Python dependencies
COPY requirements.txt /tmp/
COPY requirements/*.txt /tmp/requirements/
# Switch to /tmp to install dependencies outside home dir
WORKDIR /tmp
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r requirements/build.txt
# Install frontend dependencies using NPM
COPY package.json package-lock.json /opt/npm/

Просмотреть файл

@ -20,7 +20,8 @@ RUN mkdir /app && \
RUN apt-get update && \
apt-get install -y --no-install-recommends \
apt-transport-https build-essential curl git libpq-dev \
postgresql-client gettext sqlite3 libffi-dev && \
postgresql-client gettext sqlite3 libffi-dev \
graphviz enchant && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@ -34,10 +35,10 @@ RUN mkdir -p /opt/npm /opt/static && \
chown -R 10001:10001 /opt
# Install Python dependencies
COPY requirements.txt /tmp/
COPY requirements/*.txt /tmp/requirements/
# Switch to /tmp to install dependencies outside home dir
WORKDIR /tmp
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir -r requirements/all.txt
# Install frontend dependencies using NPM
COPY package.json package-lock.json /opt/npm/

Просмотреть файл

@ -1,4 +1,4 @@
.PHONY: build clean migrate redis-cli revision shell stop test up
.PHONY: build clean docs live-docs migrate redis-cli revision shell stop test up
help:
@echo "Welcome to the Telemetry Analysis Service\n"
@ -18,10 +18,10 @@ build:
clean: stop
docker-compose rm -f
rm -rf coverage/ .coverage
migrate:
docker-compose run web python manage.py migrate --run-syncdb
docker-compose run web \
python manage.py migrate
shell:
docker-compose run web bash
@ -37,3 +37,16 @@ test:
up:
docker-compose up
docs:
docker-compose run web \
python -m sphinx docs docs/_build/html
live-docs:
docker-compose run --service-ports web \
sphinx-autobuild \
-H 0.0.0.0 \
-p 8000 \
--watch /app/atmo \
docs \
docs/_build/html

Просмотреть файл

@ -1,6 +1,6 @@
# atmo - The code for the Telemetry Analysis Service
[![Documentation Status](https://readthedocs.org/projects/atmo/badge/?version=latest)](https://atmo.readthedocs.io/en/latest/?badge=latest)
[![Greenkeeper badge](https://badges.greenkeeper.io/mozilla/telemetry-analysis-service.svg)](https://greenkeeper.io/)
[![CircleCI](https://img.shields.io/circleci/project/github/mozilla/telemetry-analysis-service/master.svg)](https://circleci.com/gh/mozilla/telemetry-analysis-service)
[![codecov](https://codecov.io/gh/mozilla/telemetry-analysis-service/branch/master/graph/badge.svg)](https://codecov.io/gh/mozilla/telemetry-analysis-service)

105
docs/_static/fonts.css поставляемый Normal file
Просмотреть файл

@ -0,0 +1,105 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
@font-face {
font-family: 'Zilla Slab';
font-weight: normal;
font-style: normal;
src: url('fonts/ZillaSlab-Regular.woff2') format('woff2'),
url('fonts/ZillaSlab-Regular.woff') format('woff');
}
@font-face {
font-family: 'Zilla Slab';
font-weight: bold;
font-style: normal;
src: url('fonts/ZillaSlab-Bold.woff2') format('woff2'),
url('fonts/ZillaSlab-Bold.woff') format('woff');
}
@font-face {
font-family: 'Zilla Slab';
font-weight: normal;
font-style: italic;
src: url('fonts/ZillaSlab-RegularItalic.woff2') format('woff2'),
url('fonts/ZillaSlab-RegularItalic.woff') format('woff');
}
@font-face {
font-family: 'Zilla Slab';
font-weight: bold;
font-style: italic;
src: url('fonts/ZillaSlab-BoldItalic.woff2') format('woff2'),
url('fonts/ZillaSlab-BoldItalic.woff') format('woff');
}
@font-face {
font-family: 'Zilla Slab Highlight';
font-weight: normal;
font-style: normal;
src: url('fonts/ZillaSlabHighlight-Regular.woff2') format('woff2'),
url('fonts/ZillaSlabHighlight-Regular.woff') format('woff');
}
@font-face {
font-family: 'Zilla Slab Highlight';
font-weight: bold;
font-style: normal;
src: url('fonts/ZillaSlabHighlight-Bold.woff2') format('woff2'),
url('fonts/ZillaSlabHighlight-Bold.woff') format('woff');
}
/* open-sans-regular - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'),
url('fonts/open-sans-v13-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/open-sans-v13-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-italic - latin */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
src: local('Open Sans Italic'), local('OpenSans-Italic'),
url('fonts/open-sans-v13-latin-italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/open-sans-v13-latin-italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-700 - latin */
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
src: local('Open Sans Bold'), local('OpenSans-Bold'),
url('fonts/open-sans-v13-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/open-sans-v13-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* open-sans-700italic - latin */
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
url('fonts/open-sans-v13-latin-700italic.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/open-sans-v13-latin-700italic.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* roboto-slab-regular - latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 400;
src: local('Roboto Slab Regular'), local('RobotoSlab-Regular'),
url('fonts/roboto-slab-v6-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/roboto-slab-v6-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* roboto-slab-700 - latin */
@font-face {
font-family: 'Roboto Slab';
font-style: normal;
font-weight: 700;
src: local('Roboto Slab Bold'), local('RobotoSlab-Bold'),
url('fonts/roboto-slab-v6-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/roboto-slab-v6-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

Двоичные данные
docs/_static/fonts/ZillaSlab-Bold.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Bold.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-BoldItalic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-BoldItalic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Italic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Italic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Light.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Light.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-LightItalic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-LightItalic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Medium.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Medium.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-MediumItalic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-MediumItalic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Regular.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-Regular.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-SemiBold.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-SemiBold.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-SemiBoldItalic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlab-SemiBoldItalic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlabHighlight-Bold.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlabHighlight-Bold.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlabHighlight-Regular.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/ZillaSlabHighlight-Regular.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-700.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-700.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-700italic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-700italic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-italic.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-italic.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-regular.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/open-sans-v13-latin-regular.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/roboto-slab-v6-latin-700.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/roboto-slab-v6-latin-700.woff2 поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/roboto-slab-v6-latin-regular.woff поставляемый Normal file

Двоичный файл не отображается.

Двоичные данные
docs/_static/fonts/roboto-slab-v6-latin-regular.woff2 поставляемый Normal file

Двоичный файл не отображается.

77
docs/_static/style.css поставляемый Normal file
Просмотреть файл

@ -0,0 +1,77 @@
/*
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
html {
font-size: 100%;
background: #fff;
}
body {
font-size: 100%;
background: #fff;
border-top: 2px solid #fff;
color: #000;
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.5;
}
code, pre, tt {
font-family: "Roboto Mono", Monaco, Consolas, "Lucida Console", monospace;
font-size: 0.95rem;
line-height: 1.3rem;
}
code {
font-weight: bold;
}
pre {
color: #484848;
background-color: #eee;
}
h1, h2, h3, h4, h5, h6, legend {
font-weight: bold;
line-height: 1.1;
margin: 0 0 .25em;
font-family: "Zilla Slab", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
h1 {
font-size: 2.375rem;
font-family: "Zilla Slab Highlight", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
h2 { font-size: 1.75rem;}
h3 { font-size: 1.3125rem;}
h4 { font-size: 1rem;}
h5 { font-size: 1rem;}
h6 { font-size: 1rem;}
a {
color: #00a7e0;
text-decoration: none;
}
a:visited {
color: #00a7e0;
text-decoration: none;
}
strong {
font-weight: bold;
}
div.bodywrapper {
padding-right: 1rem;
}
ul.search li div.context {
color: #666;
margin: 2px 0 0 30px;
text-align: left;
}

249
docs/conf.py Normal file
Просмотреть файл

@ -0,0 +1,249 @@
# -*- coding: utf-8 -*-
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
import configurations
from better import better_theme_path
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'atmo.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Docs')
sys.path.insert(0, os.path.dirname('.'))
sys.path.insert(0, os.path.abspath('.'))
# Configure Django for autodoc usage
configurations.setup()
from django.conf import settings # noqa
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinx.ext.graphviz',
'sphinx.ext.coverage',
'sphinxcontrib.spelling',
'extensions.celery',
'extensions.django',
]
# Fontpath for blockdiag (truetype font)
# blockdiag_fontpath = '/usr/share/fonts/truetype/ipafont/ipagp.ttf'
blockdiag_html_image_format = "SVG"
# Fontpath for blockdiag (truetype font)
blockdiag_fontpath = '_static/fonts/DejaVuSans.ttf'
blockdiag_antialias = True
blockdiag_transparency = True
graphviz_output_format = 'svg'
graphviz_dot_args = [
'-Nfontsize=9',
'-Nfontname=Helvetica Neue, Helvetica, Arial, sans-serif',
'-Efontsize=9',
'-Efontname=Helvetica Neue, Helvetica, Arial, sans-serif',
'-Gfontsize=9',
'-Gfontname=Helvetica Neue, Helvetica, Arial, sans-serif'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'ATMO'
copyright = u'2017, Mozilla Foundation'
author = u'Mozilla Foundation'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The full version, including alpha/beta/rc tags.
version = release = settings.VERSION.get('version', 'development')
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'algol_nu'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# -- Options for HTML output ----------------------------------------------
html_title = '%s %s' % (project, release)
html_short_title = 'Home'
html_logo = None
html_favicon = None
html_show_sphinx = True
html_show_copyright = True
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme_path = [better_theme_path]
html_theme = 'better'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
html_theme_options = {
'showheader': False,
'showrelbartop': True,
'rightsidebar': True,
'linktotheme': False,
'cssfiles': [
'_static/fonts.css',
'_static/style.css',
],
# color of text in the footer, including links; defaults to the
# value of textcolor
'footertextcolor': '#666',
}
html_sidebars = {
'**': ['localtoc.html', 'sourcelink.html', 'searchbox.html'],
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'ATMOdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'ATMO.tex', u'ATMO Documentation',
u'Mozilla Foundation', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'atmo', u'ATMO Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'ATMO', u'ATMO Documentation',
author, 'ATMO', 'One line description of project.',
'Miscellaneous'),
]
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
'python': ('https://docs.python.org/', None),
'django': ('https://docs.djangoproject.com/en/1.11/',
'https://docs.djangoproject.com/en/1.11/_objects/'),
'allauth': ('https://django-allauth.readthedocs.io/en/latest/', None),
}
# A list of warning types to suppress arbitrary warning messages.
suppress_warnings = [
'image.nonlocal_uri',
]
celery_task_prefix = 'Task: '
spelling_lang = 'en_US'
# spelling_word_list_filename = 'spelling_wordlist.txt'
spelling_ignore_pypi_package_names = True
spelling_ignore_wiki_words = True
spelling_ignore_acronyms = True
spelling_ignore_python_builtins = True
spelling_ignore_importable_modules = True

Просмотреть файл

26
docs/extensions/celery.py Normal file
Просмотреть файл

@ -0,0 +1,26 @@
from celery.contrib.sphinx import TaskDocumenter, TaskDirective
class AtmoTaskDocumenter(TaskDocumenter):
"""
A TaskDocument subclass to fix
https://github.com/celery/celery/issues/4072 temporarily.
"""
def check_module(self):
"""Normally checks if *self.object* is really defined in the module
given by *self.modname*. But since functions decorated with the @task
decorator are instances living in the celery.local module we're
checking for that and simply agree to document those then.
"""
modname = self.get_attr(self.object, '__module__', None)
if modname and modname == 'celery.local':
return True
return super(TaskDocumenter, self).check_module()
def setup(app):
"""Setup Sphinx extension."""
app.add_autodocumenter(AtmoTaskDocumenter)
app.add_directive_to_domain('py', 'task', TaskDirective)
app.add_config_value('celery_task_prefix', '(task)', True)

75
docs/extensions/django.py Normal file
Просмотреть файл

@ -0,0 +1,75 @@
import inspect
from django import forms
from django.db import models
from django.utils.html import strip_tags
from django.utils.encoding import force_text
_field_module_map = {
'django.forms.fields': 'django.forms',
'django.forms.models': 'django.forms',
'django.db.models.fields': 'django.db.models',
}
def process_docstring(app, what, name, obj, options, lines):
# Only look at objects that inherit from Django's base model class
if inspect.isclass(obj) and (
issubclass(obj, models.Model) or
issubclass(obj, forms.ModelForm)):
# Grab the field list from the meta class
fields = obj._meta.fields
for field in fields:
if isinstance(field, str):
attname = field
field = obj.base_fields[attname]
else:
attname = field.attname
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text))
# Decode and capitalize the verbose name, for use if there isn't
# any help text
verbose_name = force_text(
getattr(field, 'verbose_name', getattr(field, 'label', field))
).capitalize()
if help_text:
# Add the model field to the end of the docstring as a param
# using the help text as the description
lines.append(':param %s: %s' % (attname, help_text))
else:
# Add the model field to the end of the docstring as a param
# using the verbose name as the description
lines.append(':param %s: %s' % (attname, verbose_name))
# Add the field's type to the docstring
if isinstance(field, models.ForeignKey):
to = field.rel.to
if isinstance(to, str):
module, name = to.split('.')
else:
module, name = to.__module__, to.__name__
lines.append(
':type %s: %s to :class:`~%s.%s`' %
(attname, type(field).__name__, module, name)
)
else:
field_cls = type(field)
module, name = field_cls.__module__, field_cls.__name__
module = _field_module_map.get(module, module)
lines.append(
':type %s: :class:`~%s.%s`' %
(attname, module, name)
)
# Return the extended docstring
return lines
def setup(app):
# Register the docstring processor with sphinx
app.connect('autodoc-process-docstring', process_docstring)

3
requirements/all.txt Normal file
Просмотреть файл

@ -0,0 +1,3 @@
-r build.txt
-r docs.txt
-r tests.txt

Просмотреть файл

@ -59,18 +59,6 @@ newrelic==2.86.3.70 \
django-session-csrf==0.7.1 \
--hash=sha256:e17177e6e2e6518ec7ce6693ad10a5c747f8571d09f4cfa9082599334421605d \
--hash=sha256:ff8c10e30d312c77fc6a6db7710e22b9383e28c03b7fe958876ca96f39aa6cf2
flake8==3.3.0 \
--hash=sha256:83905eadba99f73fbfe966598aaf1682b3eb6755d2263c5b33a4e8367d60b0d1 \
--hash=sha256:b907a26dcf5580753d8f80f1be0ec1d5c45b719f7bac441120793d1a70b03f12
pep8==1.7.0 \
--hash=sha256:4fc2e478addcf17016657dff30b2d8d611e8341fac19ccf2768802f6635d7b8a \
--hash=sha256:a113d5f5ad7a7abacef9df5ec3f2af23a20a28005921577b15dd584d099d5900
pyflakes==1.5.0 \
--hash=sha256:cc5eadfb38041f8366128786b4ca12700ed05bbf1403d808e89d57d67a3875a7 \
--hash=sha256:aa0d4dff45c0cc2214ba158d29280f8fa1129f3e87858ef825930845146337f4
mccabe==0.6.1 \
--hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
--hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
requests==2.18.1 \
--hash=sha256:6afd3371c1f4c1970497cdcace5c5ecbbe58267bf05ca1abd93d99d170803ab7 \
--hash=sha256:c6f3bdf4a4323ac7b45d01e04a6f6c20e32a052cd04de81e05103abc049ad9b9
@ -90,13 +78,8 @@ python-dateutil==2.6.0 \
--hash=sha256:62a2f8df3d66f878373fd0072eacf4ee52194ba302e00082828e0d263b0418d2 \
--hash=sha256:3acbef017340600e9ff8f2994d8f7afd6eacb295383f286466a6df3961e486f0 \
--hash=sha256:537bf2a8f8ce6f6862ad705cd68f9e405c0b5db014aa40fa29eab4335d4b1716
docutils==0.13.1 \
--hash=sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77 \
--hash=sha256:cb3ebcb09242804f84bdbf0b26504077a054da6772c6f4d625f335cc53ebf94d
six==1.10.0 \
--hash=sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1
mock==2.0.0 \
--hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1
funcsigs==1.0.2 \
--hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca
pbr==3.1.0 \
@ -117,63 +100,6 @@ oauthlib==2.0.2 \
django-redis==4.8.0 \
--hash=sha256:5229da5b07ccb8d3e3e9ee098c0b7c03e20eba48634bc456697dd73d62c68b19 \
--hash=sha256:9660332cf9de5689a7ebbe0c623c4a0de79e0916a6ae867b5d0b94759bba46c9
py==1.4.34 \
--hash=sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a \
--hash=sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3
pytest==3.1.2 \
--hash=sha256:41e618f317957505ae2e81935733d8304d84170f7e21dfb15184d6fa8d7a5230 \
--hash=sha256:795ec29fbba70b22a593691ce8bcd4bdde2dc96e8099731f73c7d8bb3ce879bf
coverage==4.4.1 \
--hash=sha256:c1456f66c536010cf9e4633a8853a9153e8fd588393695295afd4d0fc16c1d74 \
--hash=sha256:97a7ec51cdde3a386e390b159b20f247ccb478084d925c75f1faa3d26c01335e \
--hash=sha256:83e955b975666b5a07d217135e7797857ce844eb340a99e46cc25525120417c4 \
--hash=sha256:483ed14080c5301048128bb027b77978c632dd9e92e3ecb09b7e28f5b92abfcf \
--hash=sha256:ef574ab9640bcfa2f3c671831faf03f65788945fdf8efa4d4a1fffc034838e2a \
--hash=sha256:c5a205b4da3c624f5119dc4d84240789b5906bb8468902ec22dcc4aad8aa4638 \
--hash=sha256:5dea90ed140e7fa9bc00463313f9bc4a6e6aff297b4969615e7a688615c4c4d2 \
--hash=sha256:f9e83b39d29c2815a38e4118d776b482d4082b5bf9c9147fbc99a3f83abe480a \
--hash=sha256:700040c354f0230287906b1276635552a3def4b646e0145555bc9e2e5da9e365 \
--hash=sha256:7f1eacae700c66c3d7362a433b228599c9d94a5a3a52613dddd9474e04deb6bc \
--hash=sha256:13ef9f799c8fb45c446a239df68034de3a6f3de274881b088bebd7f5661f79f8 \
--hash=sha256:dfb011587e2b7299112f08a2a60d2601706aac9abde37aa1177ea825adaed923 \
--hash=sha256:381be5d31d3f0d912334cf2c159bc7bea6bfe6b0e3df6061a3bf2bf88359b1f6 \
--hash=sha256:83a477ac4f55a6ef59552683a0544d47b68a85ce6a80fd0ca6b3dc767f6495fb \
--hash=sha256:dfd35f1979da31bcabbe27bcf78d4284d69870731874af629082590023a77336 \
--hash=sha256:9681efc2d310cfc53863cc6f63e88ebe7a48124550fa822147996cb09390b6ab \
--hash=sha256:53770b20ac5b4a12e99229d4bae57af0945be87cc257fce6c6c7571a39f0c5d4 \
--hash=sha256:8801880d32f11b6df11c32a961e186774b4634ae39d7c43235f5a24368a85f07 \
--hash=sha256:16db2c69a1acbcb3c13211e9f954e22b22a729909d81f983b6b9badacc466eda \
--hash=sha256:ef43a06a960b46c73c018704051e023ee6082030f145841ffafc8728039d5a88 \
--hash=sha256:c3e2736664a6074fc9bd54fb643f5af0fc60bfedb2963b3d3f98c7450335e34c \
--hash=sha256:17709e22e4c9f5412ba90f446fb13b245cc20bf4a60377021bbff6c0f1f63e7c \
--hash=sha256:a2f7106d1167825c4115794c2ba57cc3b15feb6183db5328fa66f94c12902d8b \
--hash=sha256:2a08e978f402696c6956eee9d1b7e95d3ad042959b71bafe1f3e4557cbd6e0ac \
--hash=sha256:57f510bb16efaec0b6f371b64a8000c62e7e3b3e48e8b0a5745ade078d849814 \
--hash=sha256:0f1883eab9c19aa243f51308751b8a2a547b9b817b721cc0ecf3efb99fafbea7 \
--hash=sha256:e00fe141e22ce6e9395aa24d862039eb180c6b7e89df0bbaf9765e9aebe560a9 \
--hash=sha256:ec596e4401553caa6dd2e3349ce47f9ef82c1f1bcba5d8ac3342724f0df8d6ff \
--hash=sha256:c820a533a943ebc860acc0ce6a00dd36e0fdf2c6f619ff8225755169428c5fa2 \
--hash=sha256:b7f7283eb7badd2b8a9c6a9d6eeca200a0a24db6be79baee2c11398f978edcaa \
--hash=sha256:a5ed27ad3e8420b2d6b625dcbd3e59488c14ccc06030167bcf14ffb0f4189b77 \
--hash=sha256:d7b70b7b4eb14d0753d33253fe4f121ca99102612e2719f0993607deb30c6f33 \
--hash=sha256:4047dc83773869701bde934fb3c4792648eda7c0e008a77a0aec64157d246801 \
--hash=sha256:7a9c44400ee0f3b4546066e0710e1250fd75831adc02ab99dda176ad8726f424 \
--hash=sha256:0f649e68db74b1b5b8ca4161d08eb2b8fa8ae11af1ebfb80e80e112eb0ef5300 \
--hash=sha256:52964fae0fafef8bd283ad8e9a9665205a9fdf912535434defc0ec3def1da26b \
--hash=sha256:36aa6c8db83bc27346ddcd8c2a60846a7178ecd702672689d3ea1828eb1a4d11 \
--hash=sha256:9824e15b387d331c0fc0fef905a539ab69784368a1d6ac3db864b4182e520948 \
--hash=sha256:4a678e1b9619a29c51301af61ab84122e2f8cc7a0a6b40854b808ac6be604300 \
--hash=sha256:8bb7c8dca54109b61013bc4114d96effbf10dea136722c586bce3a5d9fc4e730 \
--hash=sha256:1a41d621aa9b6ab6457b557a754d50aaff0813fad3453434de075496fca8a183 \
--hash=sha256:0fa423599fc3d9e18177f913552cdb34a8d9ad33efcf52a98c9d4b644edb42c5 \
--hash=sha256:e61a4ba0b2686040cb4828297c7e37bcaf3a1a1c0bc0dbe46cc789dde51a80fa \
--hash=sha256:ce9ef0fc99d11d418662e36fd8de6d71b19ec87c2eab961a117cc9d087576e72
pytest-django==3.1.2 \
--hash=sha256:038ccc5a9daa1b1b0eb739ab7dce54e495811eca5ea3af4815a2a3ac45152309 \
--hash=sha256:00995c2999b884a38ae9cd30a8c00ed32b3d38c1041250ea84caf18085589662
pytest-mock==1.6.0 \
--hash=sha256:83a17cbcd4dbc7c6c9dc885a0d598f9acd11f2d5142e0718ed32e14538670c1f \
--hash=sha256:29bf62c12a67dc0e7f6d02efa2404f0b4d068b38cd64f22a06c8a16cb545a03e
contextlib2==0.5.5 \
--hash=sha256:f5260a6e679d2ff42ec91ec5252f4eeffdcf21053db9113bd0a8e4d953769c00 \
--hash=sha256:509f9419ee91cdd00ba34443217d5ca51f5a364a404e1dce9e8979cea969ca48
@ -187,18 +113,12 @@ enum34==1.1.6 \
--hash=sha256:2d81cbbe0e73112bdfe6ef8576f2238f2ba27dd0d55752a776c41d38b7da2850
configparser==3.5.0 \
--hash=sha256:5308b47021bc2340965c371f0f058cc6971a04502638d4244225c49d80db273a
pycodestyle==2.3.1 \
--hash=sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9 \
--hash=sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766
django-configurations==2.0 \
--hash=sha256:b4a4eb3ed631c2abbeb7008b5cc5d8d04b190df838e7b613731d728f674f3a2f \
--hash=sha256:be47e25d070fd005cc8fbd6c913c9ec37e83d04686937afe18ca6c579b2cdedb
django-cache-url==2.0.0 \
--hash=sha256:f0009452c4d63468714c7ff59266085947f3f3cc0947b3b2e87121bb27538d6c \
--hash=sha256:d7e7d3f3fadaa38ab7c655afafc85c2a1b06a3ddc0002af4ae021c1948307f8b
freezegun==0.3.9 \
--hash=sha256:8842688de9497c82ecb40c30274ecc676e97ac78765b0ade105a97063d5b7a11 \
--hash=sha256:783ccccd7f60968bfe49ad9e114c18ea2b63831faaaf61c1f1f71ddfde1c0eee
django-guardian==1.4.8 \
--hash=sha256:353794b2f685c588e44583e18dcc2bf5fc33b0870a344ab7a1bb00764877350d \
--hash=sha256:3e901609baddf0036af6bc920970477d3c598c91ba296936a17878d03997184f
@ -321,9 +241,6 @@ CommonMark==0.7.3 \
--hash=sha256:5f20ebd91614c8d339d4cded314894feb5d9a54c3b52c1ff9883794557149ea8
future==0.16.0 \
--hash=sha256:e39ced1ab767b5936646cedba8bcce582398233d6a627067d4c6a454c90cfedb
pytest-flake8==0.8.1 \
--hash=sha256:aa10a6db147485d71dad391d4149388904c3072194d51755f64784ff128845fd \
--hash=sha256:8efaf4595a13079197ac740a12e6a87e3403f08133a42d3ac5984474f6f91681
celery==4.0.2 \
--hash=sha256:0e5b7e0d7f03aa02061abfd27aa9da05b6740281ca1f5228a54fbf7fe74d8afa \
--hash=sha256:e3d5a6c56a73ff8f2ddd4d06dc37f4c2afe4bb4da7928b884d0725ea865ef54d
@ -353,16 +270,6 @@ furl==1.0.0 \
--hash=sha256:874dae78a19ec08dcdca83f007824c090501fa95e55e965a64fcff8b8c5e7230
orderedmultidict==0.7.11 \
--hash=sha256:dc2320ca694d90dca4ecc8b9c5fdf71ca61d6c079d6feb085ef8d41585419a36
pytest-factoryboy==1.3.1 \
--hash=sha256:fb9957975ae916b308af4bbf73f609a819e3916db2c413f1b5a5b6204f87253a
factory_boy==2.8.1 \
--hash=sha256:246f7da9caf9bf855aaa73b4963353ccb147fdd3adcbc419fa29422c5b69dd4c \
--hash=sha256:a6644e391a371be603aca8624f3dedbc5a2aa4622878c20494ba17abb4b171bb
Faker==0.7.17 \
--hash=sha256:1236c6dd61d1914d4972a1a1ffd3dba989f37d81b4ecb27c66fd2d241cfbf220 \
--hash=sha256:49cba0c3df3dac4fe5cf22d1a5799683c572172b9a0e94ec318e359339648a58
inflection==0.3.1 \
--hash=sha256:18ea7fb7a7d152853386523def08736aa8c32636b047ade55f7578c4edeb16ca
autorepr==0.3.0 \
--hash=sha256:c34567e4073630feb52d9c788fc198085e9e9de4817e3b93b7c4c534fc689f11 \
--hash=sha256:1d9010d14fb325d3961e3aa73692685563f97d6ba4a2f0f735329fb37422599c \
@ -379,9 +286,6 @@ django-celery-monitor==1.1.2 \
--hash=sha256:a044fac92828e609c37675a12d6c0ef82bd519823ca1ef41ea48e246092e27b2
django-flat-responsive==1.4.1 \
--hash=sha256:d8b9be3b5740aa6ea127390f136d9239a31816631bdbf230847301a7d734fc35
pytest-cov==2.5.1 \
--hash=sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d \
--hash=sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec
certifi==2017.4.17 \
--hash=sha256:f4318671072f030a33c7ca6acaef720ddd50ff124d1388e50c1bda4cbd6d7010 \
--hash=sha256:f7527ebf7461582ce95f7a9e03dd141ce810d40590834f4ec20cddd54234c10a
@ -391,3 +295,6 @@ chardet==3.0.4 \
urllib3==1.21.1 \
--hash=sha256:8ed6d5c1ff9d6ba84677310060d6a3a78ca3072ce0684cb3c645023009c114b1 \
--hash=sha256:b14486978518ca0901a76ba973d7821047409d7f726f22156b24e83fd71382a5
docutils==0.13.1 \
--hash=sha256:de454f1015958450b72641165c08afe7023cd7e3944396448f2fb1b0ccba9d77 \
--hash=sha256:cb3ebcb09242804f84bdbf0b26504077a054da6772c6f4d625f335cc53ebf94d

76
requirements/docs.txt Normal file
Просмотреть файл

@ -0,0 +1,76 @@
Sphinx==1.6.2 \
--hash=sha256:011c1851b5f2d9f4b1d9898162867f2bf91db5c26ad8178d3122909203bc2f6c \
--hash=sha256:67527d767dff9a2e2159c501265cff47b6d96d39e036e8b971d6c143ff303197
alabaster==0.7.10 \
--hash=sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732 \
--hash=sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0
snowballstemmer==1.2.1 \
--hash=sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89 \
--hash=sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128
Jinja2==2.9.6 \
--hash=sha256:2231bace0dfd8d2bf1e5d7e41239c06c9e0ded46e70cc1094a0aa64b0afeb054 \
--hash=sha256:ddaa01a212cd6d641401cb01b605f4a4d9f37bfc93043d7f760ec70fb99ff9ff
sphinxcontrib-websupport==1.0.1 \
--hash=sha256:7a85961326aa3a400cd4ad3c816d70ed6f7c740acd7ce5d78cd0a67825072eb9 \
--hash=sha256:f4932e95869599b89bf4f80fc3989132d83c9faa5bf633e7b5e0c25dffb75da2
Pygments==2.2.0 \
--hash=sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d \
--hash=sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc
imagesize==0.7.1 \
--hash=sha256:6ebdc9e0ad188f9d1b2cdd9bc59cbe42bf931875e829e7a595e6b3abdc05cdfb \
--hash=sha256:0ab2c62b87987e3252f89d30b7cedbec12a01af9274af9ffa48108f2c13c6062
Babel==2.4.0 \
--hash=sha256:e86ca5a3a6bb64b9bbb62b9dac37225ec0ab5dfaae3c2492ebd648266468042f \
--hash=sha256:8c98f5e5f8f5f088571f2c6bd88d530e331cbbcb95a7311a0db69d3dca7ec563
MarkupSafe==1.0 \
--hash=sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665
webcolors==1.7 \
--hash=sha256:e47e68644d41c0b1f1e4d939cfe4039bdf1ab31234df63c7a4f59d4766487206
olefile==0.44 \
--hash=sha256:61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad
sphinx-better-theme==0.13 \
--hash=sha256:17a534ab4f0477b65430bd8aedcd8cea11541ba7e13f598d1d0e9d9cd376dd0f
sphinx-autobuild==0.6.0 \
--hash=sha256:2f9262d7a35f80a18c3bcb03b2bf5a83f0a5e88b75ad922b3b1cee512c7e5cd2 \
--hash=sha256:e98473cdf26287cc81393841b293b516d078f6e475062a35ceb9fe3d739ac5f3
port-for==0.3.1 \
--hash=sha256:b16a84bb29c2954db44c29be38b17c659c9c27e33918dec16b90d375cc596f1c
watchdog==0.8.3 \
--hash=sha256:7e65882adb7746039b6f3876ee174952f8eaaa34491ba34333ddf1fe35de4162
argh==0.26.2 \
--hash=sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3 \
--hash=sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65
pathtools==0.1.2 \
--hash=sha256:7c35c5421a39bb82e58018febd90e3b6e5db34c5443aaaf742b3f33d4655f1c0
PyYAML==3.12 \
--hash=sha256:3262c96a1ca437e7e4763e2843746588a965426550f3797a79fca9c6199c431f \
--hash=sha256:16b20e970597e051997d90dc2cddc713a2876c47e3d92d59ee198700c5427736 \
--hash=sha256:e863072cdf4c72eebf179342c94e6989c67185842d9997960b3e69290b2fa269 \
--hash=sha256:bc6bced57f826ca7cb5125a10b23fd0f2fff3b7c4701d64c439a300ce665fff8 \
--hash=sha256:c01b880ec30b5a6e6aa67b09a2fe3fb30473008c85cd6a67359a1b15ed6d83a4 \
--hash=sha256:827dc04b8fa7d07c44de11fabbc888e627fa8293b695e0f99cb544fdfa1bf0d1 \
--hash=sha256:592766c6303207a20efc445587778322d7f73b161bd994f227adaa341ba212ab \
--hash=sha256:ca233c64c6e40eaa6c66ef97058cdc80e8d0157a443655baa1b2966e812807ca \
--hash=sha256:4474f8ea030b5127225b8894d626bb66c01cda098d47a2b0d3429b6700af9fd8 \
--hash=sha256:326420cbb492172dec84b0f65c80942de6cedb5233c413dd824483989c000608 \
--hash=sha256:5f84523c076ad14ff5e6c037fe1c89a7f73a3e04cf0377cb4d017014976433f3 \
--hash=sha256:0c507b7f74b3d2dd4d1322ec8a94794927305ab4cebbe89cc47fe5e81541e6e8 \
--hash=sha256:b4c423ab23291d3945ac61346feeb9a0dc4184999ede5e7c43e1ffb975130ae6 \
--hash=sha256:5ac82e411044fb129bae5cfbeb3ba626acb2af31a8d17d175004b70862a741a7
tornado==4.5.1 \
--hash=sha256:2b4618010625bcf01f187eec3148c6a3db76a2a900f7dde416330fc413274df1 \
--hash=sha256:fb0883ae46da958d06fda2e3be6c033825a0b8603c493df8a69c0237055308d9 \
--hash=sha256:0a6894559e62a186d6cc20f1c0e7318f83ae8e28922d75c4b6f83d42cc91d8b1 \
--hash=sha256:c3f4456f0ab9e62dab7ede834dcf4c89082238e97b3e67a9196572c076e716aa \
--hash=sha256:db0904a28253cfe53e7dedc765c71596f3c53bb8a866ae50123320ec1a7b73fd
livereload==2.5.1 \
--hash=sha256:5ed6506f5d526ee712da9f3739c27714e6f3376f3e481728d298efceae0ec83a \
--hash=sha256:422de10d7ea9467a1ba27cbaffa84c74b809d96fb1598d9de4b9b676adf35e2c
pyenchant==1.6.8 \
--hash=sha256:71ae3daf02e8814f1f4188f9eb77ea7a3d1b7ba9ea3732271848f37bbb87e684 \
--hash=sha256:d05f3cd04ed4582a0bca5e51e37c82db68de1d44117dd60d019a1116c142d0f3 \
--hash=sha256:7ead2ee74f1a4fc2a7199b3d6012eaaaceea03fbcadcb5df67d2f9d0d51f050a \
--hash=sha256:9614f5c8cf20fbb6e4ee881dfd6d7776fd114f958a14675ff21a8878d5490d39
sphinxcontrib-spelling==2.3.0 \
--hash=sha256:008ec060f312367222992824abed00124cce0dd31c375a89b2053010df0e3be8 \
--hash=sha256:87c870b915341d6c64365d8e8116973c9d2a6c0c55296d90f0082ef4e89132f8

93
requirements/tests.txt Normal file
Просмотреть файл

@ -0,0 +1,93 @@
flake8==3.3.0 \
--hash=sha256:83905eadba99f73fbfe966598aaf1682b3eb6755d2263c5b33a4e8367d60b0d1 \
--hash=sha256:b907a26dcf5580753d8f80f1be0ec1d5c45b719f7bac441120793d1a70b03f12
pep8==1.7.0 \
--hash=sha256:4fc2e478addcf17016657dff30b2d8d611e8341fac19ccf2768802f6635d7b8a \
--hash=sha256:a113d5f5ad7a7abacef9df5ec3f2af23a20a28005921577b15dd584d099d5900
pyflakes==1.5.0 \
--hash=sha256:cc5eadfb38041f8366128786b4ca12700ed05bbf1403d808e89d57d67a3875a7 \
--hash=sha256:aa0d4dff45c0cc2214ba158d29280f8fa1129f3e87858ef825930845146337f4
mccabe==0.6.1 \
--hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
--hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
mock==2.0.0 \
--hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1
py==1.4.34 \
--hash=sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a \
--hash=sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3
pytest==3.1.2 \
--hash=sha256:41e618f317957505ae2e81935733d8304d84170f7e21dfb15184d6fa8d7a5230 \
--hash=sha256:795ec29fbba70b22a593691ce8bcd4bdde2dc96e8099731f73c7d8bb3ce879bf
coverage==4.4.1 \
--hash=sha256:c1456f66c536010cf9e4633a8853a9153e8fd588393695295afd4d0fc16c1d74 \
--hash=sha256:97a7ec51cdde3a386e390b159b20f247ccb478084d925c75f1faa3d26c01335e \
--hash=sha256:83e955b975666b5a07d217135e7797857ce844eb340a99e46cc25525120417c4 \
--hash=sha256:483ed14080c5301048128bb027b77978c632dd9e92e3ecb09b7e28f5b92abfcf \
--hash=sha256:ef574ab9640bcfa2f3c671831faf03f65788945fdf8efa4d4a1fffc034838e2a \
--hash=sha256:c5a205b4da3c624f5119dc4d84240789b5906bb8468902ec22dcc4aad8aa4638 \
--hash=sha256:5dea90ed140e7fa9bc00463313f9bc4a6e6aff297b4969615e7a688615c4c4d2 \
--hash=sha256:f9e83b39d29c2815a38e4118d776b482d4082b5bf9c9147fbc99a3f83abe480a \
--hash=sha256:700040c354f0230287906b1276635552a3def4b646e0145555bc9e2e5da9e365 \
--hash=sha256:7f1eacae700c66c3d7362a433b228599c9d94a5a3a52613dddd9474e04deb6bc \
--hash=sha256:13ef9f799c8fb45c446a239df68034de3a6f3de274881b088bebd7f5661f79f8 \
--hash=sha256:dfb011587e2b7299112f08a2a60d2601706aac9abde37aa1177ea825adaed923 \
--hash=sha256:381be5d31d3f0d912334cf2c159bc7bea6bfe6b0e3df6061a3bf2bf88359b1f6 \
--hash=sha256:83a477ac4f55a6ef59552683a0544d47b68a85ce6a80fd0ca6b3dc767f6495fb \
--hash=sha256:dfd35f1979da31bcabbe27bcf78d4284d69870731874af629082590023a77336 \
--hash=sha256:9681efc2d310cfc53863cc6f63e88ebe7a48124550fa822147996cb09390b6ab \
--hash=sha256:53770b20ac5b4a12e99229d4bae57af0945be87cc257fce6c6c7571a39f0c5d4 \
--hash=sha256:8801880d32f11b6df11c32a961e186774b4634ae39d7c43235f5a24368a85f07 \
--hash=sha256:16db2c69a1acbcb3c13211e9f954e22b22a729909d81f983b6b9badacc466eda \
--hash=sha256:ef43a06a960b46c73c018704051e023ee6082030f145841ffafc8728039d5a88 \
--hash=sha256:c3e2736664a6074fc9bd54fb643f5af0fc60bfedb2963b3d3f98c7450335e34c \
--hash=sha256:17709e22e4c9f5412ba90f446fb13b245cc20bf4a60377021bbff6c0f1f63e7c \
--hash=sha256:a2f7106d1167825c4115794c2ba57cc3b15feb6183db5328fa66f94c12902d8b \
--hash=sha256:2a08e978f402696c6956eee9d1b7e95d3ad042959b71bafe1f3e4557cbd6e0ac \
--hash=sha256:57f510bb16efaec0b6f371b64a8000c62e7e3b3e48e8b0a5745ade078d849814 \
--hash=sha256:0f1883eab9c19aa243f51308751b8a2a547b9b817b721cc0ecf3efb99fafbea7 \
--hash=sha256:e00fe141e22ce6e9395aa24d862039eb180c6b7e89df0bbaf9765e9aebe560a9 \
--hash=sha256:ec596e4401553caa6dd2e3349ce47f9ef82c1f1bcba5d8ac3342724f0df8d6ff \
--hash=sha256:c820a533a943ebc860acc0ce6a00dd36e0fdf2c6f619ff8225755169428c5fa2 \
--hash=sha256:b7f7283eb7badd2b8a9c6a9d6eeca200a0a24db6be79baee2c11398f978edcaa \
--hash=sha256:a5ed27ad3e8420b2d6b625dcbd3e59488c14ccc06030167bcf14ffb0f4189b77 \
--hash=sha256:d7b70b7b4eb14d0753d33253fe4f121ca99102612e2719f0993607deb30c6f33 \
--hash=sha256:4047dc83773869701bde934fb3c4792648eda7c0e008a77a0aec64157d246801 \
--hash=sha256:7a9c44400ee0f3b4546066e0710e1250fd75831adc02ab99dda176ad8726f424 \
--hash=sha256:0f649e68db74b1b5b8ca4161d08eb2b8fa8ae11af1ebfb80e80e112eb0ef5300 \
--hash=sha256:52964fae0fafef8bd283ad8e9a9665205a9fdf912535434defc0ec3def1da26b \
--hash=sha256:36aa6c8db83bc27346ddcd8c2a60846a7178ecd702672689d3ea1828eb1a4d11 \
--hash=sha256:9824e15b387d331c0fc0fef905a539ab69784368a1d6ac3db864b4182e520948 \
--hash=sha256:4a678e1b9619a29c51301af61ab84122e2f8cc7a0a6b40854b808ac6be604300 \
--hash=sha256:8bb7c8dca54109b61013bc4114d96effbf10dea136722c586bce3a5d9fc4e730 \
--hash=sha256:1a41d621aa9b6ab6457b557a754d50aaff0813fad3453434de075496fca8a183 \
--hash=sha256:0fa423599fc3d9e18177f913552cdb34a8d9ad33efcf52a98c9d4b644edb42c5 \
--hash=sha256:e61a4ba0b2686040cb4828297c7e37bcaf3a1a1c0bc0dbe46cc789dde51a80fa \
--hash=sha256:ce9ef0fc99d11d418662e36fd8de6d71b19ec87c2eab961a117cc9d087576e72
pytest-django==3.1.2 \
--hash=sha256:038ccc5a9daa1b1b0eb739ab7dce54e495811eca5ea3af4815a2a3ac45152309 \
--hash=sha256:00995c2999b884a38ae9cd30a8c00ed32b3d38c1041250ea84caf18085589662
pytest-mock==1.6.0 \
--hash=sha256:83a17cbcd4dbc7c6c9dc885a0d598f9acd11f2d5142e0718ed32e14538670c1f \
--hash=sha256:29bf62c12a67dc0e7f6d02efa2404f0b4d068b38cd64f22a06c8a16cb545a03e
pycodestyle==2.3.1 \
--hash=sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9 \
--hash=sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766
freezegun==0.3.9 \
--hash=sha256:8842688de9497c82ecb40c30274ecc676e97ac78765b0ade105a97063d5b7a11 \
--hash=sha256:783ccccd7f60968bfe49ad9e114c18ea2b63831faaaf61c1f1f71ddfde1c0eee
pytest-flake8==0.8.1 \
--hash=sha256:aa10a6db147485d71dad391d4149388904c3072194d51755f64784ff128845fd \
--hash=sha256:8efaf4595a13079197ac740a12e6a87e3403f08133a42d3ac5984474f6f91681
pytest-factoryboy==1.3.1 \
--hash=sha256:fb9957975ae916b308af4bbf73f609a819e3916db2c413f1b5a5b6204f87253a
factory_boy==2.8.1 \
--hash=sha256:246f7da9caf9bf855aaa73b4963353ccb147fdd3adcbc419fa29422c5b69dd4c \
--hash=sha256:a6644e391a371be603aca8624f3dedbc5a2aa4622878c20494ba17abb4b171bb
Faker==0.7.17 \
--hash=sha256:1236c6dd61d1914d4972a1a1ffd3dba989f37d81b4ecb27c66fd2d241cfbf220 \
--hash=sha256:49cba0c3df3dac4fe5cf22d1a5799683c572172b9a0e94ec318e359339648a58
inflection==0.3.1 \
--hash=sha256:18ea7fb7a7d152853386523def08736aa8c32636b047ade55f7578c4edeb16ca
pytest-cov==2.5.1 \
--hash=sha256:03aa752cf11db41d281ea1d807d954c4eda35cfa1b21d6971966cc041bbf6e2d \
--hash=sha256:890fe5565400902b0c78b5357004aab1c814115894f4f21370e2433256a3eeec