diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f0ed21 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +docs/_build/ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..b2bf330 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/generic.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/generic.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/generic" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/generic" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/_static/forkme_right_darkblue_121621.png b/docs/_static/forkme_right_darkblue_121621.png new file mode 100644 index 0000000..146ef8a Binary files /dev/null and b/docs/_static/forkme_right_darkblue_121621.png differ diff --git a/docs/_themes/generic/layout.html b/docs/_themes/generic/layout.html new file mode 100644 index 0000000..28173de --- /dev/null +++ b/docs/_themes/generic/layout.html @@ -0,0 +1,194 @@ +{# + basic/layout.html + ~~~~~~~~~~~~~~~~~ + + Master layout template for Sphinx themes. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{%- block doctype -%} + +{%- endblock %} +{%- set reldelim1 = reldelim1 is not defined and ' »' or reldelim1 %} +{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %} +{%- set render_sidebar = (not embedded) and (not theme_nosidebar|tobool) and + (not sidebars == []) %} +{%- set url_root = pathto('', 1) %} +{%- if url_root == '#' %}{% set url_root = '' %}{% endif %} + +{%- macro relbar() %} + +{%- endmacro %} + +{%- macro sidebar() %} + {%- if render_sidebar %} +
+
+ {%- block sidebarlogo %} + {%- if logo %} + + {%- endif %} + {%- endblock %} + {%- if sidebars != None %} + {#- new style sidebar: explicitly include/exclude templates #} + {%- for sidebartemplate in sidebars %} + {%- include sidebartemplate %} + {%- endfor %} + {%- else %} + {#- old style sidebars: using blocks -- should be deprecated #} + {%- block sidebartoc %} + {%- include "localtoc.html" %} + {%- endblock %} + {%- block sidebarrel %} + {%- include "relations.html" %} + {%- endblock %} + {%- block sidebarsourcelink %} + {%- include "sourcelink.html" %} + {%- endblock %} + {%- if customsidebar %} + {%- include customsidebar %} + {%- endif %} + {%- block sidebarsearch %} + {%- include "searchbox.html" %} + {%- endblock %} + {%- endif %} +
+
+ {%- endif %} +{%- endmacro %} + + + + + {{ metatags }} + {%- if not embedded and docstitle %} + {%- set titlesuffix = " — "|safe + docstitle|e %} + {%- else %} + {%- set titlesuffix = "" %} + {%- endif %} + {%- block htmltitle %} + {{ title|striptags }}{{ titlesuffix }} + {%- endblock %} + + + {%- for cssfile in css_files %} + + {%- endfor %} + {%- if not embedded %} + + {%- for scriptfile in script_files %} + + {%- endfor %} + {%- if use_opensearch %} + + {%- endif %} + {%- if favicon %} + + {%- endif %} + {%- endif %} +{%- block linktags %} + {%- if hasdoc('about') %} + + {%- endif %} + {%- if hasdoc('genindex') %} + + {%- endif %} + {%- if hasdoc('search') %} + + {%- endif %} + {%- if hasdoc('copyright') %} + + {%- endif %} + + {%- if parents %} + + {%- endif %} + {%- if next %} + + {%- endif %} + {%- if prev %} + + {%- endif %} +{%- endblock %} +{%- block extrahead %} {% endblock %} + + +{%- block header %}{% endblock %} + +{%- block relbar1 %}{{ relbar() }}{% endblock %} + +{%- block content %} + {%- block sidebar1 %} {# possible location for sidebar #} {% endblock %} + Fork me on GitHub +
+ {%- block document %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {% block body %} {% endblock %} +
+ {%- if render_sidebar %} +
+ {%- endif %} +
+ {%- endblock %} + + {%- block sidebar2 %}{{ sidebar() }}{% endblock %} +
+
+{%- endblock %} + +{%- block relbar2 %}{{ relbar() }}{% endblock %} + +{%- block footer %} + +{%- endblock %} + + diff --git a/docs/_themes/generic/static/generic.css_t b/docs/_themes/generic/static/generic.css_t new file mode 100644 index 0000000..158b097 --- /dev/null +++ b/docs/_themes/generic/static/generic.css_t @@ -0,0 +1,221 @@ +/* + * nature.css_t + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- nature theme. + * + * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); +@import url("reset.css"); +@import url("plainwalk.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Arial, sans-serif; + font-size: 100%; + background-color: #111; + color: #555; + margin: 0; + padding: 0; +} + +div.documentwrapper { + width: 640px; + margin: 0 auto; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.document { + background-color: #eee; +} + +div.body { + background-color: #ffffff; + color: #3E4349; + padding: 15px 30px 30px 30px; +} + +div.footer { + color: #555; + width: 100%; + padding: 13px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #444; + text-decoration: underline; +} + +div.related { + background-color: #7D2823; + line-height: 32px; + color: #fff; + text-shadow: 0px 1px 0 #444; + font-size: 0.9em; +} + +div.related a { + color: #fff; +} + +div.sphinxsidebar { + font-size: 0.75em; + line-height: 1.5em; +} + +div.sphinxsidebarwrapper{ + padding: 20px 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Arial, sans-serif; + color: #222; + font-size: 1.2em; + font-weight: normal; + margin: 0; + padding: 5px 10px; + background-color: #ddd; + text-shadow: 1px 1px 0 white +} + +div.sphinxsidebar h4{ + font-size: 1.1em; +} + +div.sphinxsidebar h3 a { + color: #444; +} + + +div.sphinxsidebar p { + color: #888; + padding: 5px 20px; +} + +div.sphinxsidebar p.topless { +} + +div.sphinxsidebar ul { + margin: 10px 20px; + padding: 0; + color: #000; +} + +div.sphinxsidebar a { + color: #444; +} + +div.sphinxsidebar input { + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar input[type=text]{ + margin-left: 20px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #005B81; + text-decoration: none; +} + +a:hover { + color: #E32E00; + text-decoration: underline; +} + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + line-height: 1.5em; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.highlight{ + background-color: white; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + color: #222; + border: 1px solid #C6C9CB; + margin: 1.5em 0 1.5em 0; + font-size: 90%; + overflow: hidden; +} + +tt { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ + font-size: 1.1em; + font-family: monospace; +} + +.viewcode-back { + font-family: Arial, sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + diff --git a/docs/_themes/generic/static/plainwalk.css b/docs/_themes/generic/static/plainwalk.css new file mode 100644 index 0000000..d6975c3 --- /dev/null +++ b/docs/_themes/generic/static/plainwalk.css @@ -0,0 +1,322 @@ +/* Plainwalk CSS theme v.0.1. + * + * This CSS is suitable for theming content, generated by docutils rst + * processor. If you want to use it, just add `.plainwalk` class to HTML element + * you want to style. Also, this CSS should be used on elements, which was + * reseted with Eric Meyer's reset CSS. + * + * Warning: This theme uses CSS3's `text-shadow` property, not all browsers + * support it. + * + * Copyright (c) 2010, Andrey Popp All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials + * provided with the distribution. Neither the name of the Andrey Popp nor + * the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. THIS + * SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +.plainwalk { + background: #FAFAFA; + font-family: 'Georgia', serif; + font-size: 16px; + color: #444; +} +.plainwalk h1, +.plainwalk h2, +.plainwalk h3, +.plainwalk h4, +.plainwalk h5, +.plainwalk h6, +.plainwalk ul, +.plainwalk ol, +.plainwalk dl, +.plainwalk p, +.plainwalk blockquote { + padding: 7px 0; +} + +.plainwalk h1 a, +.plainwalk h2 a, +.plainwalk h3 a, +.plainwalk h4 a, +.plainwalk h5 a, +.plainwalk h6 a { + text-decoration: none; +} + +.plainwalk img { + padding-bottom: 0px; +} +.plainwalk h1, +.plainwalk h2, +.plainwalk h3, +.plainwalk h4, +.plainwalk h5, +.plainwalk h6 { + font-weight: normal; +} +.plainwalk p, +.plainwalk li { + line-height: 1.45em; +} +/* elements */ +.plainwalk table { + margin: 10px 0; +} +.plainwalk dt { + font-style: italic; + font-weight: bold; + margin-bottom: 1px; +} +.plainwalk dd { + margin-left: 20px; + margin-bottom: 10px; +} +.plainwalk tt { + font-size: 90%; + white-space: nowrap; + padding: 0 3px; +} +.plainwalk tt, +.plainwalk pre { + font-family: Consolas, Monaco, Menlo, 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace !important; + background: #F1F1F1; +} +.plainwalk pre { + font-size: 85%; + line-height: 120%; + display: block; + padding: 10px; +} +.plainwalk img { + display: block; +} +.plainwalk em { + font-style: italic; +} +.plainwalk strong { + font-weight: bold; +} +.plainwalk hr{ + border: 1px solid #F1F1F1; + border-width: 0 0 1px 0; + margin: 10px 10px 10px 10px; +} +/* headings */ +.plainwalk h1 { + font-size: 196%; + font-style: normal; + color:#7D2823; +} +.plainwalk h2 { + font-size: 167%; + font-style: normal; + color:#7D2823; +} +.plainwalk h3 { + font-size:146.5%; + font-style: normal; + color:#A2332C; +} +.plainwalk h4 { + font-size: 123.1%; + font-style: normal; + color: #A2332C; +} +.plainwalk h5 { + font-size: 108%; + font-style: italic; + color:#A2332C; +} +.plainwalk h6 { + font-size: 108%; + font-style: italic; + color:#000000; +} +/* links */ +.plainwalk a { + color: #7D2823; + text-decoration: underline; +} +.plainwalk a:focus, +.plainwalk a:hover { + color:#A2332C; + text-decoration: underline; +} +.plainwalk a:visited { + color:#1F1F1F; +} +.plainwalk h1 a { + color:#7D2823; +} +.plainwalk h2 a { + color:#7D2823; +} +.plainwalk h3 a { + color:#A2332C; +} +.plainwalk h4 a { + color: #A2332C; +} +.plainwalk h5 a { + color: #A2332C; +} +.plainwalk h6 a { + color: #000; +} +.plainwalk h1 a:visited { + color:#7D2823; +} +.plainwalk h2 a:visited { + color:#7D2823; +} +.plainwalk h3 a:visited { + color:#A2332C; +} +.plainwalk h4 a:visited { + color: #A2332C; +} +.plainwalk h5 a:visited { + color: #A2332C; +} +.plainwalk h6 a:visited { + color: #000; +} +/* numbered list */ +.plainwalk ol li { + list-style-type: decimal; + margin-left: 40px; +} +.plainwalk ol.upperalpha li { + list-style-type: upper-latin; +} +.plainwalk ol.loweralpha li { + list-style-type: lower-latin; +} +.plainwalk ol.upperroman li { + list-style-type: upper-roman; +} +.plainwalk ol.lowerroman li { + list-style-type: lower-roman; +} +/* standard list */ +.plainwalk ul li { + list-style-type: square; + margin-left:40px; + margin-bottom: 3px; +} +/* quotes */ +.plainwalk blockquote { + color: #AAA; + font-size: 95%; + font-style: italic; + border-left: 2px solid #EEE; + padding-left: 10px; +} +/* sidebar */ +.plainwalk .sidebar { + float: right; + width: 40%; + padding: 10px; + margin: 5px; + background: #F1F1F1; + font-size: 90%; +} +.plainwalk .sidebar-title { + font-size:110%; + font-weight:normal; + font-style: italic; + color:#A2332C; + padding: 0; +} +.plainwalk .sidebar .last { + padding: 0; +} +/* admonition */ +.plainwalk .admonition, +.plainwalk .note, +.plainwalk .attention, +.plainwalk .caution, +.plainwalk .danger, +.plainwalk .error, +.plainwalk .hint, +.plainwalk .important, +.plainwalk .tip, +.plainwalk .warning +{ + margin: 10px 0; + padding: 10px; + background: #F1F1F1; + font-size: 90%; +} +.plainwalk .admonition-title { + font-size:110%; + margin-right: 5px; + display: inline; + color:#A2332C; + padding: 0; +} +.plainwalk .admonition .last, +.plainwalk .note .last, +.plainwalk .caution .last, +.plainwalk .attention .last, +.plainwalk .danger .last, +.plainwalk .error .last, +.plainwalk .hint .last, +.plainwalk .important .last, +.plainwalk .tip .last, +.plainwalk .warning .last { display: inline; } +/* footnote */ +.plainwalk a.fn-backref, +.plainwalk a.footnote-reference { + text-decoration: none; +} +.plainwalk table.footnote td { + font-size: 95%; + padding: 5px; +} +/* plainwalks */ +.plainwalk .plainwalks .topic-title { + font-size:110%; + color:#A2332C; + margin:0; + padding-bottom:0; +} +/* docinfo */ +.plainwalk table.docinfo { + font-size: 90%; +} +.plainwalk table.docinfo td, +.plainwalk table.docinfo th { + padding: 2px; +} +.plainwalk table.docinfo th { + text-align: right; +} +/* css3 fancies */ +.plainwalk.css3 h1, +.plainwalk.css3 h2, +.plainwalk.css3 h3, +.plainwalk.css3 h4, +.plainwalk.css3 h5, +.plainwalk.css3 h6 +{ text-shadow: 1px 1px 0px #EEE; } +.plainwalk.css3 pre { text-shadow:none; } diff --git a/docs/_themes/generic/static/reset.css b/docs/_themes/generic/static/reset.css new file mode 100644 index 0000000..1c85489 --- /dev/null +++ b/docs/_themes/generic/static/reset.css @@ -0,0 +1,53 @@ +/* http://meyerweb.com/eric/tools/css/reset/ */ +/* v1.0 | 20080212 */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +/* remember to define focus styles! */ +:focus { + outline: 0; +} + +/* remember to highlight inserts somehow! */ +ins { + text-decoration: none; +} +del { + text-decoration: line-through; +} + +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/docs/_themes/generic/theme.conf b/docs/_themes/generic/theme.conf new file mode 100644 index 0000000..8c36b82 --- /dev/null +++ b/docs/_themes/generic/theme.conf @@ -0,0 +1,4 @@ +[theme] +inherit = basic +stylesheet = generic.css +pygments_style = tango diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..66872c9 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +# +# generic documentation build configuration file, created by +# sphinx-quickstart on Mon Jul 19 01:35:17 2010. +# +# 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. + +import sys, os + +# 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. +#sys.path.append(os.path.abspath('.')) + +# -- 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.coverage'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'generic' +copyright = u'2010, Andrey Popp' + +# 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 short X.Y version. +version = '0.2' +# The full version, including alpha/beta/rc tags. +release = '0.2' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'generic' + +# 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 = {"nosidebar": True} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ["./_themes"] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# 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'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'genericdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'generic.tex', u'generic Documentation', + u'Andrey Popp', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'generic', u'generic Documentation', + [u'Andrey Popp'], 1) +] + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..f9b0865 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,214 @@ +.. generic documentation master file, created by + sphinx-quickstart on Mon Jul 19 01:35:17 2010. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Generic documentation +================================ + +.. toctree:: + :maxdepth: 2 + +Generic is a programming library for Python that provides tools for generic +programming. By, now there is only one feature -- multiple dispatch. + +Multiple dispatch +----------------- + +Multiple dispatch (or multidispatch) is a technique of choosing the function +implementation at runtime based on its argument types. For illustrating the +problem, let's see example function that behaves differently when you provide +it ``str`` or ``int`` object as argument:: + + def add_two(x): + if isinstance(x, int): + return add_two_int(x) + elif isinstance(x, str): + return add_two_str(x) + else: + raise TypeError("Wrong argument type.") + + def add_two_int(x): + return x + 2 + + def add_two_str(x): + return x + "2" + + assert add_two(2) == 4 + assert add_two("2") == "22" + +The last two assertions are true -- the function ``add_two`` dispatches their +execution either to ``add_two_int`` or ``add_two_str`` depending on its +argument type. As for me, this piece of code is very verbose and unpythonic. +This is there ``generic.multidispatch`` comes in place. + + +Declaring multifunctions +~~~~~~~~~~~~~~~~~~~~~~~~ + +With help of ``generic.multidispatch`` module we can rewrite the latter +piece of code like that:: + + from generic.multidispatch import multifunction + + @multifunction(int) + def add_two(x): + return x + 2 + + @add_two.when(str) + def add_two(x): + return x + "2" + + assert add_two(2) == 4 + assert add_two("2") == "22" + +And again -- assertions are fulfilled, but now code is more readable and +declarative. + +Furthermore, this way of writing functions is more extensible, because we can +add another branch (another implementation for some other argument type) to our +function ``add_two`` by being able not to modify original declarations, even if +they are defined in another module or package:: + + from mymodule import add_two + + @add_two.when(list) + def add_two(x): + return x + [2] + +Doing the same thing for function from first example would require modify +function code for each type we want to handle, which isn't good. + + +Overriding multifunction implementations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you're trying to define multifunction implementation for types, that already have another implementation, then ``TypeError`` exception would be raised. But there is a way to do this kind of things in explicitly manner:: + + @add_two.override(list) + def add_two(x): + return x + [2, 2] + +Note the using of the ``@add_two.override`` decorator instead of the +``@add_two.when`` one. + + +Multifunctions with more than one arguments +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The example from the previous section demonstrates basic usage of +``generic.multidispatch`` for defining multifunctions with single argument. +Now, let's see how we can define multifunctions with more than one arguments:: + + @multifunction(int, int) + def add(x, y): + return x + y + + @add.when(str, str) + def add(x, y): + return add(int(x), int(y)) + +This is as simple as it can be -- just pass more types to ``multifunction`` +decorator to produce multifunction that dispatches by exactly that number of +arguments. + +If function takes more arguments than the number of types you have passed to +``multifunction`` decorator, they will be treated as typical arguments and +there will be no dispatching by them. The same holds for keyword and variable +(prefixed with ``*`` or ``**``) arguments. + +The only requirements for declaring multifunctions are: + +* The number of function's positional arguments should not be less than the + number of types passed to ``multifunction`` decorator. This is because + dispatching is allowed only by positional arguments. + +* All function implementations that are related to one multifunction should + have the same arity for positional arguments. + + +Declaring multimethods +~~~~~~~~~~~~~~~~~~~~~~ + +*Generic* can help with defining multifunctions, but what about methods? There +are another decorators for them:: + + from generic.multidispatch import multimethod + from generic.multidispatch import has_multimethods + + @has_multimethods + class A(object): + + @multimethod(int) + def foo(self, x): + return x + 1 + + @foo.when(str) + def foo(self, x): + return x + "1" + + assert A().foo(1) == 2 + assert A().foo("1") == "11" + +It may seen works exactly like multifunctions, but it's not. The main +difference between multifunctions and multimethods is that the latter is +dispatched also by its class type. This is why we need another decorator +``has_multimethods`` for classes that define multimethods. + +.. warning:: + Decorating class with ``has_multimethods`` decorator is mandatory to + multimethods declaration to work. This is because we cannot know method's + class at the time of method declaration. + +Let's see example demonstrates usage of that feature:: + + @has_multimethods + class B(A): + + @A.foo.when(list) + def foo(self, x): + return x + [1] + + assert B().foo(1) == 2 + assert B().foo("1") == "11" + assert B().foo([1]) == [1, 1] + +As you can see, we have extended method ``foo`` inherits all previous +declarations, but also adds another one -- for ``list`` type. Note, that declaration is only works for ``B`` objects, but not for ``A`` ones:: + + A().foo([1]) # bad! raises TypeError + + +Also, note, that all multimethods declarations are overridden implicitly, so +the ``A.foo.override`` and ``A.foo.when`` decorators are the same. + +All other things that are true for multifunctions are also hold for +multimethods. + +Development +----------- + +Development of *generic* library takes place at `github +`_ -- there are code repository and issue +tracker. + +API referrence +-------------- + +.. autofunction:: generic.multidispatch.multifunction + +.. autofunction:: generic.multidispatch.multimethod + +.. autofunction:: generic.multidispatch.has_multimethods + +.. autoclass:: generic.multidispatch.FunctionDispatcher + +.. autoclass:: generic.multidispatch.MethodDispatcher + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` +