moved lots of files

This commit is contained in:
mdipierro
2013-08-25 20:29:54 -05:00
committed by Michele Comitini
parent f18b264ca1
commit cd704f74bb
73 changed files with 11 additions and 5988 deletions
+2 -2
View File
@@ -20,7 +20,7 @@ clean:
epydoc:
### build epydoc
rm -f -r applications/examples/static/epydoc/
epydoc --config epydoc.conf
epydoc --config extras/epydoc/epydoc.conf
cp applications/examples/static/title.png applications/examples/static/epydoc
tests:
python web2py.py --run_system_tests
@@ -54,7 +54,7 @@ src:
### build web2py_src.zip
echo '' > NEWINSTALL
mv web2py_src.zip web2py_src_old.zip | echo 'no old'
cd ..; zip -r web2py/web2py_src.zip web2py/gluon/*.py web2py/gluon/contrib/* web2py/splashlogo.gif web2py/*.py web2py/README.markdown web2py/LICENSE web2py/CHANGELOG web2py/NEWINSTALL web2py/VERSION web2py/Makefile web2py/epydoc.css web2py/epydoc.conf web2py/app.example.yaml web2py/logging.example.conf web2py/queue.example.yaml web2py/MANIFEST.in web2py/w2p_apps web2py/w2p_clone web2py/w2p_run web2py/web2py.cio web2py/web2py.gif web2py/scripts/*.sh web2py/scripts/*.py web2py/applications/admin web2py/applications/examples/ web2py/applications/welcome web2py/applications/__init__.py web2py/site-packages/__init__.py web2py/gluon/tests/*.sh web2py/gluon/tests/*.py
cd ..; zip -r web2py/web2py_src.zip web2py/gluon/*.py web2py/gluon/contrib/* web2py/extras/* web2py/examples/* web2py/README.markdown web2py/LICENSE web2py/CHANGELOG web2py/NEWINSTALL web2py/VERSION web2py/MANIFEST.in web2py/scripts/*.sh web2py/scripts/*.py web2py/applications/admin web2py/applications/examples/ web2py/applications/welcome web2py/applications/__init__.py web2py/site-packages/__init__.py web2py/gluon/tests/*.sh web2py/gluon/tests/*.py
mdp:
make src
+3 -1
View File
@@ -33,7 +33,7 @@ That's it!!!
... > other handlers and example files
gluon/ > the core libraries
contrib/ > third party libraries
tests/ > unittests
tests/ > unittests
applications/ > are the apps
admin/ > web based IDE
...
@@ -54,6 +54,8 @@ That's it!!!
cron/
tests/
... > your own apps
examples/ > example config files, mv .. and customize
extras/ > other files which are required for building web2py
scripts/ > utility and installation scripts
site-packages/ > additional optional modules
+1 -1
View File
@@ -1 +1 @@
Version 2.6.0-development+timestamp.2013.08.25.19.34.35
Version 2.6.0-development+timestamp.2013.08.25.20.29.04
-88
View File
@@ -1,88 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@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 " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@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 build/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
@echo
@echo "Build finished. The HTML pages are in build/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) build/dirhtml
@echo
@echo "Build finished. The HTML pages are in build/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in build/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) build/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in build/qthelp, like this:"
@echo "# qcollectiongenerator build/qthelp/Web2Py.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile build/qthelp/Web2Py.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
@echo
@echo "Build finished; the LaTeX files are in build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
@echo
@echo "The overview file is in build/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in build/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) build/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in build/doctest/output.txt."
-42
View File
@@ -1,42 +0,0 @@
"""Convert a FAQ (AlterEgo) markdown dump into ReSt documents using pandoc
**Todo**
#. add titles
#. add logging
#. add CLI with optparse
"""
import os
import sys
import glob
import subprocess
import logging
indir = 'faq_markdown'
outdir = 'faq_rst'
inpath = os.path.join('.', indir)
outpath = os.path.join('.', outdir)
pattern = inpath + '/*.txt'
out_ext = 'rst'
for file in glob.glob(pattern):
infile = file
file_basename = os.path.basename(file)
outfile_name = os.path.splitext(file_basename)[0] + '.' + out_ext
outfile = os.path.join(outpath, outfile_name)
# pandoc -s -w rst --toc README -o example6.text
logging.info("converting file %s to format <%s>" % (file_basename, out_ext))
convert_call = ["pandoc",
"-s",
"-w", out_ext,
infile,
"-o", outfile
]
p = subprocess.call(convert_call)
logging.info("Finshed!")
-258
View File
@@ -1,258 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Sropulpof
# Copyright (C) 2008 Société des arts technologiques (SAT)
# http://www.sat.qc.ca
# All rights reserved.
#
# This file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Sropulpof is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Sropulpof. If not, see <http:#www.gnu.org/licenses/>.
"""
This script parse a directory tree looking for python modules and packages and
create ReST files appropriately to create code documentation with Sphinx.
It also create a modules index.
"""
import os
import optparse
# automodule options
options = ['members',
'undoc-members',
# 'inherited-members', # disable because there's a bug in sphinx
'show-inheritance']
def create_file_name(base, opts):
"""Create file name from base name, path and suffix"""
return os.path.join(opts.destdir, "%s.%s" % (base, opts.suffix))
def write_directive(module):
"""Create the automodule directive and add the options"""
directive = '.. automodule:: %s\n' % module
for option in options:
directive += ' :%s:\n' % option
return directive
def write_heading(module, kind='Module'):
"""Create the page heading."""
module = module.title()
heading = title_line(module + ' Documentation', '=')
heading += 'This page contains the %s %s documentation.\n\n' % (module, kind)
return heading
def write_sub(module, kind='Module'):
"""Create the module subtitle"""
sub = title_line('The :mod:`%s` %s' % (module, kind), '-')
return sub
def title_line(title, char):
""" Underline the title with the character pass, with the right length."""
return '%s\n%s\n\n' % (title, len(title) * char)
def create_module_file(root, module, opts):
"""Build the text of the file and write the file."""
name = create_file_name(module, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
elif check_for_code('%s/%s.py' % (root, module)): # don't build the file if there's no code in it
print 'Creating file %s for module.' % name
text = write_heading(module)
text += write_sub(module)
text += write_directive(module)
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def create_package_file(root, subroot, py_files, opts, subs=None):
"""Build the text of the file and write the file."""
package = root.rpartition('/')[2].lower()
name = create_file_name(subroot, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
else:
print 'Creating file %s for package.' % name
text = write_heading(package, 'Package')
if subs == None:
subs = []
else:
# build a list of directories that are package (they contain an __init_.py file)
subs = [sub for sub in subs if os.path.isfile('%s/%s/__init__.py' % (root, sub))]
# if there's some package directories, add a TOC for theses subpackages
if subs:
text += title_line('Subpackages', '-')
text += '.. toctree::\n\n'
for sub in subs:
text += ' %s.%s\n' % (subroot, sub)
text += '\n'
# add each package's module
for py_file in py_files:
if not check_for_code('%s/%s' % (root, py_file)):
# don't build the file if there's no code in it
continue
py_file = py_file[:-3]
py_path = '%s.%s' % (subroot, py_file)
kind = "Module"
if py_file == '__init__':
kind = "Package"
text += write_sub(kind == 'Package' and package or py_file, kind)
text += write_directive(kind == "Package" and subroot or py_path)
text += '\n'
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def check_for_code(module):
"""
Check if there's at least one class or one function in the module.
"""
fd = open(module, 'r')
for line in fd:
if line.startswith('def ') or line.startswith('class '):
fd.close()
return True
fd.close()
return False
def recurse_tree(path, excludes, opts):
"""
Look for every file in the directory tree and create the corresponding
ReST files.
"""
toc = []
excludes = format_excludes(path, excludes)
tree = os.walk(path, False)
for root, subs, files in tree:
# keep only the Python script files
py_files = check_py_file(files)
# remove hidden ('.') and private ('_') directories
subs = [sub for sub in subs if sub[0] not in ['.', '_']]
# check if there's valid files to process
if "/." in root or "/_" in root \
or not py_files \
or check_excludes(root, excludes):
continue
subroot = root[len(path):].lstrip('/').replace('/', '.')
if root == path:
# we are at the root level so we create only modules
for py_file in py_files:
module = py_file[:-3]
create_module_file(root, module, opts)
toc.append(module)
elif not subs and "__init__.py" in py_files:
# we are in a package without sub package
create_package_file(root, subroot, py_files, opts=opts)
toc.append(subroot)
elif "__init__.py" in py_files:
# we are in package with subpackage(s)
create_package_file(root, subroot, py_files, opts, subs)
toc.append(subroot)
# create the module's index
if not opts.notoc:
modules_toc(toc, opts)
def modules_toc(modules, opts, name='modules'):
"""
Create the module's index.
"""
fname = create_file_name(name, opts)
if not opts.force and os.path.exists(fname):
print "File %s already exists." % name
return
print "Creating module's index modules.txt."
text = write_heading(opts.header, 'Modules')
text += title_line('Modules:', '-')
text += '.. toctree::\n'
text += ' :maxdepth: %s\n\n' % opts.maxdepth
modules.sort()
prev_module = ''
for module in modules:
# look if the module is a subpackage and, if yes, ignore it
if module.startswith(prev_module + '.'):
continue
prev_module = module
text += ' %s\n' % module
# write the file
if not opts.dryrun:
fd = open(fname, 'w')
fd.write(text)
fd.close()
def format_excludes(path, excludes):
"""
Format the excluded directory list.
(verify that the path is not from the root of the volume or the root of the
package)
"""
f_excludes = []
for exclude in excludes:
if exclude[0] != '/' and exclude[:len(path)] != path:
exclude = '%s/%s' % (path, exclude)
# remove trailing slash
f_excludes.append(exclude.rstrip('/'))
return f_excludes
def check_excludes(root, excludes):
"""
Check if the directory is in the exclude list.
"""
for exclude in excludes:
if root[:len(exclude)] == exclude:
return True
return False
def check_py_file(files):
"""
Return a list with only the python scripts (remove all other files).
"""
py_files = [fich for fich in files if fich[-3:] == '.py']
return py_files
if __name__ == '__main__':
parser = optparse.OptionParser(usage="""usage: %prog [options] <package path> [exclude paths, ...]
Note: By default this script will not overwrite already created files.""")
parser.add_option("-n", "--doc-header", action="store", dest="header", help="Documentation Header (default=Project)", default="Project")
parser.add_option("-d", "--dest-dir", action="store", dest="destdir", help="Output destination directory", default="")
parser.add_option("-s", "--suffix", action="store", dest="suffix", help="module suffix (default=txt)", default="txt")
parser.add_option("-m", "--maxdepth", action="store", dest="maxdepth", help="Maximum depth of submodules to show in the TOC (default=4)", type="int", default=4)
parser.add_option("-r", "--dry-run", action="store_true", dest="dryrun", help="Run the script without creating the files")
parser.add_option("-f", "--force", action="store_true", dest="force", help="Overwrite all the files")
parser.add_option("-t", "--no-toc", action="store_true", dest="notoc", help="Don't create the table of content file")
(opts, args) = parser.parse_args()
if len(args) < 1:
parser.error("package path is required.")
else:
if os.path.isdir(args[0]):
# if there's some exclude arguments, build the list of excludes
excludes = args[1:]
recurse_tree(args[0], excludes, opts)
else:
print '%s is not a valid directory.' % args
-3
View File
@@ -1,3 +0,0 @@
:: run from web2py root folder because of autodoc & web2py import behaviour!!!!
sphinx-build -b html -w doc\sphinx-build.log -Ea doc/source applications/examples/static/sphinx
::sphinx-build -b html -w sphinx-build.log -Ea source ../applications/examples/static/sphinx
-3
View File
@@ -1,3 +0,0 @@
# run from web2py root folder because of autodoc & web2py import behaviour!!!!
sphinx-build -b html -w doc/sphinx-build.log -Ea doc/source applications/examples/static/sphinx
#sphinx-build -b html -w sphinx-build.log -Ea source ../applications/examples/static/sphinx
-112
View File
@@ -1,112 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set ALLSPHINXOPTS=-d build/doctrees %SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
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. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over 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
goto end
)
if "%1" == "clean" (
for /d %%i in (build\*) do rmdir /q /s %%i
del /q /s build\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% build/html
echo.
echo.Build finished. The HTML pages are in build/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% build/dirhtml
echo.
echo.Build finished. The HTML pages are in build/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% build/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% build/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% build/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in build/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% build/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in build/qthelp, like this:
echo.^> qcollectiongenerator build\qthelp\Web2Py.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile build\qthelp\Web2Py.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% build/latex
echo.
echo.Build finished; the LaTeX files are in build/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% build/changes
echo.
echo.The overview file is in build/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% build/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in build/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% build/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in build/doctest/output.txt.
goto end
)
:end
-7
View File
@@ -1,7 +0,0 @@
faq
=======
web2py_DAL_understands_Django_and_SQLAlchemy_models.rst
docstrings
=============
Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

-22
View File
@@ -1,22 +0,0 @@
.. note:: There is an `ongoing discussion
<http://thread.gmane.org/gmane.comp.python.web2py/8538/focus=8633>`_,
on whether this part of the *web2py* documents should be
included in the developer documentation.
This discussion involves:
* the `AlterEgo (FAQ) <http://www.web2py.com/AlterEgo>`_
* the `User Wiki <https://mdp.cti.depaul.edu/wiki>`_
Until this is resolved, the parts under question will be excluded.
Nevertheless, these party are still available and can be included in
the Sphinx build by the following steps:
#. back up the directory ``web2py/doc``
#. unzip the archive ``external_input.zip`` delivered with the
documentation in the directory
``web2py/doc``.
Existing files should be overwritten.
#. re-build the documentation
-251
View File
@@ -1,251 +0,0 @@
# -*- coding: utf-8 -*-
#
# Web2Py documentation build configuration file, created by
# sphinx-quickstart on Thu Apr 30 17:10:06 2009.
#
# 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('.'))
#--- sys.path for web2py_modules
web2py_modules = os.path.join('.', '..', '..')
sys.path.append(os.path.abspath(web2py_modules))
#print sys.path
#from gluon import *
##--- sys.path for helper packages
sys.path.extend([
#
# local extension
os.path.join(os.path.dirname(__file__), '..', 'sphinxext', 'local'),
# numpy standard doc extensions
os.path.join(os.path.dirname(__file__), '..', 'sphinxext', 'numpydoc'),
#
# # _static files
os.path.join(os.path.dirname(__file__), '_static')
])
#
#
#import sphinx_tools as st
##--- autogenerate API docs
### Auxilary
#script_path = os.path.abspath(
# os.path.join(
# '..', 'sphinxext', 'local', 'generate_modules_modif.py'))
#dest_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'contents', 'lib', 'gluon'))
#print 'dest', dest_dir
#package_dir = os.path.abspath(os.path.join(web2py_modules, 'gluon'))
#print 'package_dir', package_dir
#doc_header = (os.path.split(dest_dir)[-1]).capitalize()
#p = st.autogenerate_package_doc(script_path, dest_dir,
# package_dir,
# doc_header,
# suffix='rst',
# overwrite=True)
# -- General configuration -----------------------------------------------------
# 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.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'numpydoc']
# 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'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Web2Py'
copyright = u'2009, The web2py developers'
# 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.
#--- get version
version_file = open(os.path.join('..', '..', 'VERSION'), 'r')
version_content = version_file.read()
version_str = version_content.split('(')[0].strip()
version_str = version_str.split(' ')
# The short X.Y version.
version = version_str[1]
# The full version, including alpha/beta/rc tags.
release = version_str[1]
if len(version_str) > 2:
release += + ' ' + version_str[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 documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = []
# 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. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
html_theme = 'default'
# 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 = {}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> 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 = '_static/pics/logo_colored_small.png'
# 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_use_modindex = 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, an OpenSearch description file will be output, and all pages will
# contain a <link> 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 = 'Web2Pydoc'
# -- 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', 'Web2Py.tex', u'Web2Py Documentation',
u'The web2py developers', '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
# 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_use_modindex = True
# Example configuration for intersphinx: refer to the Python standard library.
#--- Intersphinx
intersphinx_mapping = {'http://docs.python.org/dev': None,
}
#--- CUSTOM
keep_warnings = True
todo_include_todos = True
-100
View File
@@ -1,100 +0,0 @@
**********************************
Introduction for documenting
**********************************
.. rubric:: Some hints on writing documentation with Sphinx for web2py
Writing documentation
========================
official documentation
----------------------------------
* `Sphinx <http://sphinx.pocoo.org/contents.html>`_
Docstrings
------------------------
* official python standard
* `Docstring Conventions <http://www.python.org/dev/peps/pep-0257>`_
* `Documenting Python <http://docs.python.org/dev/documenting/index.html>`_
* numpy standard
* `documentation standard <http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard>`_
* `Example file <http://projects.scipy.org/numpy/browser/trunk/doc/example.py>`_
* `Docstring Template <http://projects.scipy.org/numpy/browser/trunk/doc/EXAMPLE_DOCSTRING.txt>`_
If you use `Eclipse / Pydev <http://pydev.sourceforge.net/>`_ you can define this piece as template.
Helpers
------------------------
Editors
________________________
* `Emacs: see docutils page <http://docutils.sourceforge.net/docs/user/emacs.html>`_
* `Gedit (Linux) <http://textmethod.com/wiki/ReStructuredTextToolsForGedit>`_
* `Ulipad (Win) <http://code.google.com/p/ulipad>`_
Others
________________________
* creating tables in ReST can be painful. Here is a module that can help::
easy_install prettytable
import prettytable as pt
mytable =pt.PrettyTable(["id", "category", "recipie"])
print mytable # copy & paste this into your ReST document!
mytable_string = mytable.get_string() # or insert this string when
generating automatic documents
Building documentation
========================
Follow these steps:
#. easy_install -U sphinx
#. built with custom make files for web2py => **Note: we could create a
cross-platform python script for this!**
#. unix-like: ``sh doc/make-doc_html.sh``
#. windows: ``doc\make-doc_html.bat``
Due to the special manner of the *web2py* import mechanism it requires that
the doc is built from the *web2py* root directory.
#. the result will written to: ``web2py/applications/examples/static/sphinx``
(the target directory will be automatically created)
#. inspect any error
#. on the :term:`CLI`: see the errors and warnings floating on
``stderr``/``stdout``
#. using the above mentioned make files a log file will be written to
``web2py/doc/sphinx-build.log``
Contributing
========================
.. warning:: Please ask on the
`Mailinglist <http://groups.google.com/group/web2py>`_ before
commiting or pushing to the repositories.
So far, it has not been agreed on a proper setup to mutually
edit the documentation and especially how to correct the
docstrings without getting to many :term:`DVCS` conflicts.
#. branch the web2py Sphinx code::
bzr branch lp:~web2py/web2py/web2py-sphinx
cd web2py-sphinx
#. pull the latest code from web2py Sphinx branch::
bzr pull
#. pull latest web2py development version::
bzr pull http://bazaar.launchpad.net/~mdipierro/web2py/devel/
#. change and edit the documents or docstrings with your edior
#. push the changes to the web2py Sphinx branch::
bzr push lp:~web2py/web2py/web2py-sphinx
This requires that you are a member of the `web2py team at Launchpad <https://launchpad.net/~web2py>`_ and registered at Launchpad `with your SSA keys <https://help.launchpad.net/YourAccount/CreatingAnSSHKeyPair>`_. You can find more info on the `Launchpad help page <https://help.launchpad.net/Code/UploadingABranch>`_
-9
View File
@@ -1,9 +0,0 @@
Frequently Asked Questions (FAQ)
==================================
.. rubric:: The pages from the `AlterEgo <http://www.web2py.com/AlterEgo>`_
.. note:: These pages are extracted as plain and not yet converted into
:term:`ReSt` formated documents.
.. include:: _static/rst/external_hint.txt
-15
View File
@@ -1,15 +0,0 @@
***************************
Glossary
***************************
.. glossary::
:sorted:
ReSt
ReStructured Text ASCII markup format
CLI
Command Line Interface
DVCS
Distributed Version Control System
-13
View File
@@ -1,13 +0,0 @@
Compat Documentation
====================
This page contains the Compat Package documentation.
The :mod:`uuid` Module
----------------------
.. automodule:: gluon.compat.uuid
:members:
:undoc-members:
:show-inheritance:
@@ -1,13 +0,0 @@
Gateways Documentation
======================
This page contains the Gateways Package documentation.
The :mod:`fcgi` Module
----------------------
.. automodule:: gluon.contrib.gateways.fcgi
:members:
:undoc-members:
:show-inheritance:
@@ -1,21 +0,0 @@
Markdown Documentation
======================
This page contains the Markdown Package documentation.
The :mod:`markdown` Package
---------------------------
.. automodule:: gluon.contrib.markdown
:members:
:undoc-members:
:show-inheritance:
The :mod:`markdown2` Module
---------------------------
.. automodule:: gluon.contrib.markdown.markdown2
:members:
:undoc-members:
:show-inheritance:
@@ -1,21 +0,0 @@
Memcache Documentation
======================
This page contains the Memcache Package documentation.
The :mod:`memcache` Module
--------------------------
.. automodule:: gluon.contrib.memcache.memcache
:members:
:undoc-members:
:show-inheritance:
The :mod:`memcache` Package
---------------------------
.. automodule:: gluon.contrib.memcache
:members:
:undoc-members:
:show-inheritance:
-53
View File
@@ -1,53 +0,0 @@
Pyrtf Documentation
===================
This page contains the Pyrtf Package documentation.
The :mod:`Elements` Module
--------------------------
.. automodule:: gluon.contrib.pyrtf.Elements
:members:
:undoc-members:
:show-inheritance:
The :mod:`Renderer` Module
--------------------------
.. automodule:: gluon.contrib.pyrtf.Renderer
:members:
:undoc-members:
:show-inheritance:
The :mod:`PropertySets` Module
------------------------------
.. automodule:: gluon.contrib.pyrtf.PropertySets
:members:
:undoc-members:
:show-inheritance:
The :mod:`pyrtf` Package
------------------------
.. automodule:: gluon.contrib.pyrtf
:members:
:undoc-members:
:show-inheritance:
The :mod:`Constants` Module
---------------------------
.. automodule:: gluon.contrib.pyrtf.Constants
:members:
:undoc-members:
:show-inheritance:
The :mod:`Styles` Module
------------------------
.. automodule:: gluon.contrib.pyrtf.Styles
:members:
:undoc-members:
:show-inheritance:
-80
View File
@@ -1,80 +0,0 @@
Contrib Documentation
=====================
This page contains the Contrib Package documentation.
Subpackages
-----------
.. toctree::
gluon.contrib.pyrtf
gluon.contrib.gateways
gluon.contrib.markdown
gluon.contrib.memcache
gluon.contrib.simplejson
The :mod:`feedparser` Module
----------------------------
.. automodule:: gluon.contrib.feedparser
:members:
:undoc-members:
:show-inheritance:
The :mod:`memdb` Module
-----------------------
.. automodule:: gluon.contrib.memdb
:members:
:undoc-members:
:show-inheritance:
The :mod:`rss2` Module
----------------------
.. automodule:: gluon.contrib.rss2
:members:
:undoc-members:
:show-inheritance:
The :mod:`wsgihooks` Module
---------------------------
.. automodule:: gluon.contrib.wsgihooks
:members:
:undoc-members:
:show-inheritance:
The :mod:`taskbar_widget` Module
--------------------------------
.. automodule:: gluon.contrib.taskbar_widget
:members:
:undoc-members:
:show-inheritance:
The :mod:`cron` Module
----------------------
.. automodule:: gluon.contrib.cron
:members:
:undoc-members:
:show-inheritance:
The :mod:`gae_memcache` Module
------------------------------
.. automodule:: gluon.contrib.gae_memcache
:members:
:undoc-members:
:show-inheritance:
The :mod:`gql` Module
---------------------
.. automodule:: gluon.contrib.gql
:members:
:undoc-members:
:show-inheritance:
@@ -1,37 +0,0 @@
Simplejson Documentation
========================
This page contains the Simplejson Package documentation.
The :mod:`encoder` Module
-------------------------
.. automodule:: gluon.contrib.simplejson.encoder
:members:
:undoc-members:
:show-inheritance:
The :mod:`simplejson` Package
-----------------------------
.. automodule:: gluon.contrib.simplejson
:members:
:undoc-members:
:show-inheritance:
The :mod:`scanner` Module
-------------------------
.. automodule:: gluon.contrib.simplejson.scanner
:members:
:undoc-members:
:show-inheritance:
The :mod:`decoder` Module
-------------------------
.. automodule:: gluon.contrib.simplejson.decoder
:members:
:undoc-members:
:show-inheritance:
-220
View File
@@ -1,220 +0,0 @@
Gluon Package
===================
This page contains the Gluon Package documentation.
Subpackages
-----------
.. toctree::
gluon.compat
gluon.contrib
The :mod:`validators` Module
----------------------------
.. automodule:: gluon.validators
:members:
:undoc-members:
:show-inheritance:
The :mod:`sql` Module
---------------------
.. automodule:: gluon.sql
:members:
:undoc-members:
:show-inheritance:
The :mod:`xmlrpc` Module
------------------------
.. automodule:: gluon.xmlrpc
:members:
:undoc-members:
:show-inheritance:
The :mod:`shell` Module
-----------------------
.. automodule:: gluon.shell
:members:
:undoc-members:
:show-inheritance:
The :mod:`utils` Module
-----------------------
.. automodule:: gluon.utils
:members:
:undoc-members:
:show-inheritance:
The :mod:`globals` Module
-------------------------
.. automodule:: gluon.globals
:members:
:undoc-members:
:show-inheritance:
The :mod:`compileapp` Module
----------------------------
.. automodule:: gluon.compileapp
:members:
:undoc-members:
:show-inheritance:
The :mod:`wsgiserver` Module
----------------------------
.. automodule:: gluon.wsgiserver
:members:
:undoc-members:
:show-inheritance:
The :mod:`winservice` Module
----------------------------
.. automodule:: gluon.winservice
:members:
:undoc-members:
:show-inheritance:
The :mod:`template` Module
--------------------------
.. automodule:: gluon.template
:members:
:undoc-members:
:show-inheritance:
The :mod:`fileutils` Module
---------------------------
.. automodule:: gluon.fileutils
:members:
:undoc-members:
:show-inheritance:
The :mod:`sqlhtml` Module
-------------------------
.. automodule:: gluon.sqlhtml
:members:
:undoc-members:
:show-inheritance:
The :mod:`tools` Module
-----------------------
.. automodule:: gluon.tools
:members:
:undoc-members:
:show-inheritance:
The :mod:`languages` Module
---------------------------
.. automodule:: gluon.languages
:members:
:undoc-members:
:show-inheritance:
The :mod:`streamer` Module
--------------------------
.. automodule:: gluon.streamer
:members:
:undoc-members:
:show-inheritance:
The :mod:`restricted` Module
----------------------------
.. automodule:: gluon.restricted
:members:
:undoc-members:
:show-inheritance:
The :mod:`http` Module
----------------------
.. automodule:: gluon.http
:members:
:undoc-members:
:show-inheritance:
The :mod:`storage` Module
-------------------------
.. automodule:: gluon.storage
:members:
:undoc-members:
:show-inheritance:
The :mod:`highlight` Module
---------------------------
.. automodule:: gluon.highlight
:members:
:undoc-members:
:show-inheritance:
The :mod:`cache` Module
-----------------------
.. automodule:: gluon.cache
:members:
:undoc-members:
:show-inheritance:
The :mod:`sanitizer` Module
---------------------------
.. automodule:: gluon.sanitizer
:members:
:undoc-members:
:show-inheritance:
The :mod:`main` Module
----------------------
.. automodule:: gluon.main
:members:
:undoc-members:
:show-inheritance:
The :mod:`widget` Module
------------------------
.. automodule:: gluon.widget
:members:
:undoc-members:
:show-inheritance:
The :mod:`rewrite` Module
-------------------------
.. automodule:: gluon.rewrite
:members:
:undoc-members:
:show-inheritance:
The :mod:`html` Module
----------------------
.. automodule:: gluon.html
:members:
:undoc-members:
:show-inheritance:
The :mod:`contenttype` Module
-----------------------------
.. automodule:: gluon.contenttype
:members:
:undoc-members:
:show-inheritance:
-91
View File
@@ -1,91 +0,0 @@
.. Web2Py documentation master file, created by
sphinx-quickstart on Thu Apr 30 17:10:06 2009.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Web2Py's documentation!
==================================
.. warning:: This is a BETA version of the Sphinx based documentation for
*web2py*. **It is subject to change!**
.. note:: The documentation at the current stage is intended for develpers
and contributors. They shall have the possibility to test their
docstrings and markup.
.. note:: Please read :doc:`docs_contrib` for instructions to Sphinx
documentation writing for *web2py*!
Contents
===================
General Documents
-------------------
.. toctree::
:maxdepth: 2
docs_contrib
docs_overview
web2py_todo
glossary
Contributed Documents
------------------------
.. toctree::
:maxdepth: 1
user_wiki
faq
.. User Wiki
-------------------
.. rubric:: The pages from the `User Wiki <https://mdp.cti.depaul.edu/wiki>`_
.. note:: According to an `ongoing discussion <http://thread.gmane.org/gmane.comp.python.web2py/8304/focus=8512>`_,
the page order and structure may be
changed in the future.
.. on error do::
rename 's/\.txt/\.rst/' *.txt
.. toctree::
:maxdepth: 2
:glob:
user_wiki/*
.. Frequently Asked Questions (FAQ)
----------------------------------
.. rubric:: The pages from the `AlterEgo <http://www.web2py.com/AlterEgo>`_
.. note:: These pages are extracted as plain and not yet converted into
:term:`ReSt` formated documents.
.. toctree::
:maxdepth: 2
:glob:
faq/*
Modules
-------------------
.. toctree::
:maxdepth: 2
modules
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
-10
View File
@@ -1,10 +0,0 @@
Web2Py Modules
====================
.. rubric:: This page contains the Web2Py Modules documentation.
.. toctree::
:maxdepth: 5
gluon/gluon
-6
View File
@@ -1,6 +0,0 @@
User Wiki
===================
.. rubric:: The pages from the `User Wiki <https://mdp.cti.depaul.edu/wiki>`_
.. include:: _static/rst/external_hint.txt
-28
View File
@@ -1,28 +0,0 @@
***************************
Todo & Feature Proposals
***************************
Documentation
========================
#. update or create a .bzrignore
#. correct docstrings
#. add more hand written documentation.
#. customise sphinx theme
#. colors
#. fix long lines
#. decide finally what to do with FAQ and wiki
#. FAQ
#. document API doc and add the script (``generate_modules.py``) to
tools
#. fix FAQ docs
#. User Wiki
#. document wiki markdown to :term`ReSt` conversion and add the script
(``convert_faq.py``)to tools
#. fix ``user_wiki`` docs
Proposed new features
========================
#. new feature x
#. new feature z
-258
View File
@@ -1,258 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Sropulpof
# Copyright (C) 2008 Société des arts technologiques (SAT)
# http://www.sat.qc.ca
# All rights reserved.
#
# This file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Sropulpof is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Sropulpof. If not, see <http:#www.gnu.org/licenses/>.
"""
This script parse a directory tree looking for python modules and packages and
create ReST files appropriately to create code documentation with Sphinx.
It also create a modules index.
"""
import os
import optparse
# automodule options
options = ['members',
'undoc-members',
# 'inherited-members', # disable because there's a bug in sphinx
'show-inheritance']
def create_file_name(base, opts):
"""Create file name from base name, path and suffix"""
return os.path.join(opts.destdir, "%s.%s" % (base, opts.suffix))
def write_directive(module):
"""Create the automodule directive and add the options"""
directive = '.. automodule:: %s\n' % module
for option in options:
directive += ' :%s:\n' % option
return directive
def write_heading(module, kind='Module'):
"""Create the page heading."""
module = module.title()
heading = title_line(module + ' Documentation', '=')
heading += 'This page contains the %s %s documentation.\n\n' % (module, kind)
return heading
def write_sub(module, kind='Module'):
"""Create the module subtitle"""
sub = title_line('The :mod:`%s` %s' % (module, kind), '-')
return sub
def title_line(title, char):
""" Underline the title with the character pass, with the right length."""
return '%s\n%s\n\n' % (title, len(title) * char)
def create_module_file(root, module, opts):
"""Build the text of the file and write the file."""
name = create_file_name(module, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
elif check_for_code('%s/%s.py' % (root, module)): # don't build the file if there's no code in it
print 'Creating file %s for module.' % name
text = write_heading(module)
text += write_sub(module)
text += write_directive(module)
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def create_package_file(root, subroot, py_files, opts, subs=None):
"""Build the text of the file and write the file."""
package = root.rpartition('/')[2].lower()
name = create_file_name(subroot, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
else:
print 'Creating file %s for package.' % name
text = write_heading(package, 'Package')
if subs == None:
subs = []
else:
# build a list of directories that are package (they contain an __init_.py file)
subs = [sub for sub in subs if os.path.isfile('%s/%s/__init__.py' % (root, sub))]
# if there's some package directories, add a TOC for theses subpackages
if subs:
text += title_line('Subpackages', '-')
text += '.. toctree::\n\n'
for sub in subs:
text += ' %s.%s\n' % (subroot, sub)
text += '\n'
# add each package's module
for py_file in py_files:
if not check_for_code('%s/%s' % (root, py_file)):
# don't build the file if there's no code in it
continue
py_file = py_file[:-3]
py_path = '%s.%s' % (subroot, py_file)
kind = "Module"
if py_file == '__init__':
kind = "Package"
text += write_sub(kind == 'Package' and package or py_file, kind)
text += write_directive(kind == "Package" and subroot or py_path)
text += '\n'
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def check_for_code(module):
"""
Check if there's at least one class or one function in the module.
"""
fd = open(module, 'r')
for line in fd:
if line.startswith('def ') or line.startswith('class '):
fd.close()
return True
fd.close()
return False
def recurse_tree(path, excludes, opts):
"""
Look for every file in the directory tree and create the corresponding
ReST files.
"""
toc = []
excludes = format_excludes(path, excludes)
tree = os.walk(path, False)
for root, subs, files in tree:
# keep only the Python script files
py_files = check_py_file(files)
# remove hidden ('.') and private ('_') directories
subs = [sub for sub in subs if sub[0] not in ['.', '_']]
# check if there's valid files to process
if "/." in root or "/_" in root \
or not py_files \
or check_excludes(root, excludes):
continue
subroot = root[len(path):].lstrip('/').replace('/', '.')
if root == path:
# we are at the root level so we create only modules
for py_file in py_files:
module = py_file[:-3]
create_module_file(root, module, opts)
toc.append(module)
elif not subs and "__init__.py" in py_files:
# we are in a package without sub package
create_package_file(root, subroot, py_files, opts=opts)
toc.append(subroot)
elif "__init__.py" in py_files:
# we are in package with subpackage(s)
create_package_file(root, subroot, py_files, opts, subs)
toc.append(subroot)
# create the module's index
if not opts.notoc:
modules_toc(toc, opts)
def modules_toc(modules, opts, name='modules'):
"""
Create the module's index.
"""
fname = create_file_name(name, opts)
if not opts.force and os.path.exists(fname):
print "File %s already exists." % name
return
print "Creating module's index modules.txt."
text = write_heading(opts.header, 'Modules')
text += title_line('Modules:', '-')
text += '.. toctree::\n'
text += ' :maxdepth: %s\n\n' % opts.maxdepth
modules.sort()
prev_module = ''
for module in modules:
# look if the module is a subpackage and, if yes, ignore it
if module.startswith(prev_module + '.'):
continue
prev_module = module
text += ' %s\n' % module
# write the file
if not opts.dryrun:
fd = open(fname, 'w')
fd.write(text)
fd.close()
def format_excludes(path, excludes):
"""
Format the excluded directory list.
(verify that the path is not from the root of the volume or the root of the
package)
"""
f_excludes = []
for exclude in excludes:
if exclude[0] != '/' and exclude[:len(path)] != path:
exclude = '%s/%s' % (path, exclude)
# remove trailing slash
f_excludes.append(exclude.rstrip('/'))
return f_excludes
def check_excludes(root, excludes):
"""
Check if the directory is in the exclude list.
"""
for exclude in excludes:
if root[:len(exclude)] == exclude:
return True
return False
def check_py_file(files):
"""
Return a list with only the python scripts (remove all other files).
"""
py_files = [fich for fich in files if fich[-3:] == '.py']
return py_files
if __name__ == '__main__':
parser = optparse.OptionParser(usage="""usage: %prog [options] <package path> [exclude paths, ...]
Note: By default this script will not overwrite already created files.""")
parser.add_option("-n", "--doc-header", action="store", dest="header", help="Documentation Header (default=Project)", default="Project")
parser.add_option("-d", "--dest-dir", action="store", dest="destdir", help="Output destination directory", default="")
parser.add_option("-s", "--suffix", action="store", dest="suffix", help="module suffix (default=txt)", default="txt")
parser.add_option("-m", "--maxdepth", action="store", dest="maxdepth", help="Maximum depth of submodules to show in the TOC (default=4)", type="int", default=4)
parser.add_option("-r", "--dry-run", action="store_true", dest="dryrun", help="Run the script without creating the files")
parser.add_option("-f", "--force", action="store_true", dest="force", help="Overwrite all the files")
parser.add_option("-t", "--no-toc", action="store_true", dest="notoc", help="Don't create the table of content file")
(opts, args) = parser.parse_args()
if len(args) < 1:
parser.error("package path is required.")
else:
if os.path.isdir(args[0]):
# if there's some exclude arguments, build the list of excludes
excludes = args[1:]
recurse_tree(args[0], excludes, opts)
else:
print '%s is not a valid directory.' % args
@@ -1,271 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Sropulpof
# Copyright (C) 2008 Société des arts technologiques (SAT)
# http://www.sat.qc.ca
# All rights reserved.
#
# This file is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Sropulpof is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Sropulpof. If not, see <http:#www.gnu.org/licenses/>.
"""
This script parse a directory tree looking for python modules and packages and
create ReST files appropriately to create code documentation with Sphinx.
It also create a modules index.
"""
import os
import optparse
# automodule options
options = ['members',
'undoc-members',
# 'inherited-members', # disable because there's a bug in sphinx
'show-inheritance']
def create_file_name(base, opts):
"""Create file name from base name, path and suffix"""
return os.path.join(opts.destdir, "%s.%s" % (base, opts.suffix))
def write_directive(package, module):
"""Create the automodule directive and add the options"""
directive = '.. automodule:: %s.%s\n' % (package, module)
for option in options:
directive += ' :%s:\n' % option
return directive
def write_heading(module, kind='Module'):
"""Create the page heading."""
module = module.title()
heading = title_line(module + ' Documentation', '=')
heading += 'This page contains the %s %s documentation.\n\n' % (module, kind)
return heading
def write_sub(module, kind='Module'):
"""Create the module subtitle"""
sub = title_line('The :mod:`%s` %s' % (module, kind), '-')
return sub
def title_line(title, char):
""" Underline the title with the character pass, with the right length."""
return '%s\n%s\n\n' % (title, len(title) * char)
def create_module_file(root, package, module, opts):
"""Build the text of the file and write the file."""
name = create_file_name(module, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
elif check_for_code('%s/%s.py' % (root, module)): # don't build the file if there's no code in it
print 'Creating file %s for module.' % name
text = write_heading(module)
text += write_sub(module)
text += write_directive(package, module)
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def create_package_file(root, subroot, py_files, opts, subs=None):
"""Build the text of the file and write the file."""
package = root.rpartition('/')[2].lower()
name = create_file_name(subroot, opts)
if not opts.force and os.path.isfile(name):
print 'File %s already exists.' % name
else:
print 'Creating file %s for package.' % name
text = write_heading(package, 'Package')
if subs == None:
subs = []
else:
# build a list of directories that are package (they contain an __init_.py file)
subs = [sub for sub in subs if os.path.isfile('%s/%s/__init__.py' % (root, sub))]
# if there's some package directories, add a TOC for theses subpackages
if subs:
text += title_line('Subpackages', '-')
text += '.. toctree::\n\n'
for sub in subs:
text += ' %s.%s\n' % (subroot, sub)
text += '\n'
# add each package's module
for py_file in py_files:
if not check_for_code('%s/%s' % (root, py_file)):
# don't build the file if there's no code in it
continue
py_file = py_file[:-3]
py_path = '%s.%s' % (subroot, py_file)
kind = "Module"
if py_file == '__init__':
kind = "Package"
text += write_sub(kind == 'Package' and package or py_file, kind)
text += write_directive(kind == "Package" and subroot or py_path)
text += '\n'
# write the file
if not opts.dryrun:
fd = open(name, 'w')
fd.write(text)
fd.close()
def check_for_code(module):
"""
Check if there's at least one class or one function in the module.
"""
fd = open(module, 'r')
for line in fd:
if line.startswith('def ') or line.startswith('class '):
fd.close()
return True
fd.close()
return False
def recurse_tree(path, excludes, opts):
"""
Look for every file in the directory tree and create the corresponding
ReST files.
"""
package_name = os.path.split(path)[-1]
print 'package name', package_name
toc = []
excludes = format_excludes(path, excludes)
tree = os.walk(path, False)
for root, subs, files in tree:
# keep only the Python script files
py_files = check_py_file(files)
# remove hidden ('.') and private ('_') directories
subs = [sub for sub in subs if sub[0] not in ['.', '_']]
# check if there's valid files to process
if "/." in root or "/_" in root \
or not py_files \
or check_excludes(root, excludes):
continue
subroot = root[len(path):].lstrip('/').replace('/', '.')
if root == path:
# we are at the root level so we create only modules
for py_file in py_files:
module = py_file[:-3]
create_module_file(root, package_name, module, opts)
if not check_for_code(os.path.join(path, module+'.py')):
# don't build the file if there's no code in it
pass
else:
toc.append(module)
elif not subs and "__init__.py" in py_files:
# we are in a package without sub package
create_package_file(root, subroot, py_files, opts=opts)
# FIXME: HERE THE __init__.py should go into the toc only if it contains
# code!
if not check_for_code(subroot):
# don't build the file if there's no code in it
continue
toc.append(subroot)
print 'here'
elif "__init__.py" in py_files:
# we are in package with subpackage(s)
create_package_file(root, subroot, py_files, opts, subs)
toc.append(subroot)
print 'hello'
# create the module's index
if not opts.notoc:
modules_toc(toc, opts)
def modules_toc(modules, opts, name='modules'):
"""
Create the module's index.
"""
fname = create_file_name(name, opts)
if not opts.force and os.path.exists(fname):
print "File %s already exists." % name
return
print "Creating module's index modules.txt."
text = write_heading(opts.header, 'Modules')
text += title_line('Modules:', '-')
text += '.. toctree::\n'
text += ' :maxdepth: %s\n\n' % opts.maxdepth
modules.sort()
prev_module = ''
for module in modules:
# look if the module is a subpackage and, if yes, ignore it
if module.startswith(prev_module + '.'):
continue
prev_module = module
text += ' %s\n' % module
# write the file
if not opts.dryrun:
fd = open(fname, 'w')
fd.write(text)
fd.close()
def format_excludes(path, excludes):
"""
Format the excluded directory list.
(verify that the path is not from the root of the volume or the root of the
package)
"""
f_excludes = []
for exclude in excludes:
if exclude[0] != '/' and exclude[:len(path)] != path:
exclude = '%s/%s' % (path, exclude)
# remove trailing slash
f_excludes.append(exclude.rstrip('/'))
return f_excludes
def check_excludes(root, excludes):
"""
Check if the directory is in the exclude list.
"""
for exclude in excludes:
if root[:len(exclude)] == exclude:
return True
return False
def check_py_file(files):
"""
Return a list with only the python scripts (remove all other files).
"""
py_files = [fich for fich in files if fich[-3:] == '.py']
return py_files
if __name__ == '__main__':
parser = optparse.OptionParser(usage="""usage: %prog [options] <package path> [exclude paths, ...]
Note: By default this script will not overwrite already created files.""")
parser.add_option("-n", "--doc-header", action="store", dest="header", help="Documentation Header (default=Project)", default="Project")
parser.add_option("-d", "--dest-dir", action="store", dest="destdir", help="Output destination directory", default="")
parser.add_option("-s", "--suffix", action="store", dest="suffix", help="module suffix (default=txt)", default="txt")
parser.add_option("-m", "--maxdepth", action="store", dest="maxdepth", help="Maximum depth of submodules to show in the TOC (default=4)", type="int", default=4)
parser.add_option("-r", "--dry-run", action="store_true", dest="dryrun", help="Run the script without creating the files")
parser.add_option("-f", "--force", action="store_true", dest="force", help="Overwrite all the files")
parser.add_option("-t", "--no-toc", action="store_true", dest="notoc", help="Don't create the table of content file")
(opts, args) = parser.parse_args()
if len(args) < 1:
parser.error("package path is required.")
else:
if os.path.isdir(args[0]):
# if there's some exclude arguments, build the list of excludes
excludes = args[1:]
recurse_tree(args[0], excludes, opts)
else:
print '%s is not a valid directory.' % args
-87
View File
@@ -1,87 +0,0 @@
import os
import subprocess
import codecs
#--- BZR: changelog information
def write_changelog_bzr(repo_path, output_dir,
output_file='bzr_revision_log.txt',
target_encoding='utf-8'):
"""Write the bzr changelog to a file which can then be included in the documentation
"""
bzr_logfile_path = os.path.join(output_dir, output_file)
bzr_logfile = codecs.open(bzr_logfile_path, 'w', encoding=target_encoding)
try:
p_log = subprocess.Popen(('bzr log --short'),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1)
(stdout, stderr) = p_log.communicate()
bzr_logfile.write(stdout)
finally:
bzr_logfile.close()
#UnicodeDecodeError: 'ascii' codec can't decode byte 0x81 in position 2871: ordinal not in range(128)
# like bzr version-info --format python > vers_test.py
#--- BZR: version info
def write_version_info_bzr(repo_path, output_dir, output_file='_version.py'):
"""Write the version information from BZR repository into a version file.
Parameters
----------
repo_path : string
Path to the BZR repository root
repo_path : string
Path to the output directory where the version info is saved
detail, e.g. ``(N,) ndarray`` or ``array_like``.
output_file : string
output file name
Returns
-------
p_info : subprocess_obj
contents of the `func:`suprocess.Popen` returns
"""
bzr_version_filepath = os.path.join(output_dir, output_file)
bzr_version_file = open(bzr_version_filepath, 'w')
p_info = subprocess.Popen(('bzr version-info --format python'),
stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=-1)
(stdout, stderr) = p_info.communicate()
bzr_version_file.write(stdout)
bzr_version_file.close()
return p_info
#--- auto generate documentation
def autogenerate_package_doc(script_path, dest_dir,
package_dir,
doc_header,
suffix='rst',
overwrite=False):
"""Autogenerate package API ReSt documents
"""
print script_path
if overwrite:
force = '--force'
p_apidoc = subprocess.Popen(('python', script_path,
'--dest-dir='+dest_dir,
'--suffix='+suffix,
'--doc-header='+doc_header,
force,
package_dir), bufsize=-1)
'sphinxext\local\generate_modules_modif.py --dest-dir=source\contents\lib\auxilary\generated --suffix=rst --force --doc-header=Auxilary ..\..\modules_local\auxilary'
return p_apidoc
if __name__ == "__main__":
repo_path = os.path.join('..', '.')
output_dir = os.path.join('.')
write_changelog_bzr(repo_path, output_dir, output_file='changelog.txt')
-97
View File
@@ -1,97 +0,0 @@
-------------------------------------------------------------------------------
The files
- numpydoc.py
- autosummary.py
- autosummary_generate.py
- docscrape.py
- docscrape_sphinx.py
- phantom_import.py
have the following license:
Copyright (C) 2008 Stefan van der Walt <stefan@mentat.za.net>, Pauli Virtanen <pav@iki.fi>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-------------------------------------------------------------------------------
The files
- compiler_unparse.py
- comment_eater.py
- traitsdoc.py
have the following license:
This software is OSI Certified Open Source Software.
OSI Certified is a certification mark of the Open Source Initiative.
Copyright (c) 2006, Enthought, Inc.
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 Enthought, Inc. 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 OWNER 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.
-------------------------------------------------------------------------------
The files
- only_directives.py
- plot_directive.py
originate from Matplotlib (http://matplotlib.sf.net/) which has
the following license:
Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved.
1. This LICENSE AGREEMENT is between John D. Hunter (“JDH”), and the Individual or Organization (“Licensee”) accessing and otherwise using matplotlib software in source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, JDH hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use matplotlib 0.98.3 alone or in any derivative version, provided, however, that JDHs License Agreement and JDHs notice of copyright, i.e., “Copyright (c) 2002-2008 John D. Hunter; All Rights Reserved” are retained in matplotlib 0.98.3 alone or in any derivative version prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on or incorporates matplotlib 0.98.3 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to matplotlib 0.98.3.
4. JDH is making matplotlib 0.98.3 available to Licensee on an “AS IS” basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB 0.98.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB 0.98.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING MATPLOTLIB 0.98.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between JDH and Licensee. This License Agreement does not grant permission to use JDH trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.
8. By copying, installing or otherwise using matplotlib 0.98.3, Licensee agrees to be bound by the terms and conditions of this License Agreement.
-2
View File
@@ -1,2 +0,0 @@
recursive-include tests *.py
include *.txt
-1
View File
@@ -1 +0,0 @@
from numpydoc import setup
-349
View File
@@ -1,349 +0,0 @@
"""
===========
autosummary
===========
Sphinx extension that adds an autosummary:: directive, which can be
used to generate function/method/attribute/etc. summary lists, similar
to those output eg. by Epydoc and other API doc generation tools.
An :autolink: role is also provided.
autosummary directive
---------------------
The autosummary directive has the form::
.. autosummary::
:nosignatures:
:toctree: generated/
module.function_1
module.function_2
...
and it generates an output table (containing signatures, optionally)
======================== =============================================
module.function_1(args) Summary line from the docstring of function_1
module.function_2(args) Summary line from the docstring
...
======================== =============================================
If the :toctree: option is specified, files matching the function names
are inserted to the toctree with the given prefix:
generated/module.function_1
generated/module.function_2
...
Note: The file names contain the module:: or currentmodule:: prefixes.
.. seealso:: autosummary_generate.py
autolink role
-------------
The autolink role functions as ``:obj:`` when the name referred can be
resolved to a Python object, and otherwise it becomes simple emphasis.
This can be used as the default role to make links 'smart'.
"""
import sys, os, posixpath, re
from docutils.parsers.rst import directives
from docutils.statemachine import ViewList
from docutils import nodes
import sphinx.addnodes, sphinx.roles
from sphinx.util import patfilter
from docscrape_sphinx import get_doc_object
import warnings
warnings.warn(
"The numpydoc.autosummary extension can also be found as "
"sphinx.ext.autosummary in Sphinx >= 0.6, and the version in "
"Sphinx >= 0.7 is superior to the one in numpydoc. This numpydoc "
"version of autosummary is no longer maintained.",
DeprecationWarning, stacklevel=2)
def setup(app):
app.add_directive('autosummary', autosummary_directive, True, (0, 0, False),
toctree=directives.unchanged,
nosignatures=directives.flag)
app.add_role('autolink', autolink_role)
app.add_node(autosummary_toc,
html=(autosummary_toc_visit_html, autosummary_toc_depart_noop),
latex=(autosummary_toc_visit_latex, autosummary_toc_depart_noop))
app.connect('doctree-read', process_autosummary_toc)
#------------------------------------------------------------------------------
# autosummary_toc node
#------------------------------------------------------------------------------
class autosummary_toc(nodes.comment):
pass
def process_autosummary_toc(app, doctree):
"""
Insert items described in autosummary:: to the TOC tree, but do
not generate the toctree:: list.
"""
env = app.builder.env
crawled = {}
def crawl_toc(node, depth=1):
crawled[node] = True
for j, subnode in enumerate(node):
try:
if (isinstance(subnode, autosummary_toc)
and isinstance(subnode[0], sphinx.addnodes.toctree)):
env.note_toctree(env.docname, subnode[0])
continue
except IndexError:
continue
if not isinstance(subnode, nodes.section):
continue
if subnode not in crawled:
crawl_toc(subnode, depth+1)
crawl_toc(doctree)
def autosummary_toc_visit_html(self, node):
"""Hide autosummary toctree list in HTML output"""
raise nodes.SkipNode
def autosummary_toc_visit_latex(self, node):
"""Show autosummary toctree (= put the referenced pages here) in Latex"""
pass
def autosummary_toc_depart_noop(self, node):
pass
#------------------------------------------------------------------------------
# .. autosummary::
#------------------------------------------------------------------------------
def autosummary_directive(dirname, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
"""
Pretty table containing short signatures and summaries of functions etc.
autosummary also generates a (hidden) toctree:: node.
"""
names = []
names += [x.strip().split()[0] for x in content
if x.strip() and re.search(r'^[a-zA-Z_]', x.strip()[0])]
table, warnings, real_names = get_autosummary(names, state,
'nosignatures' in options)
node = table
env = state.document.settings.env
suffix = env.config.source_suffix
all_docnames = env.found_docs.copy()
dirname = posixpath.dirname(env.docname)
if 'toctree' in options:
tree_prefix = options['toctree'].strip()
docnames = []
for name in names:
name = real_names.get(name, name)
docname = tree_prefix + name
if docname.endswith(suffix):
docname = docname[:-len(suffix)]
docname = posixpath.normpath(posixpath.join(dirname, docname))
if docname not in env.found_docs:
warnings.append(state.document.reporter.warning(
'toctree references unknown document %r' % docname,
line=lineno))
docnames.append(docname)
tocnode = sphinx.addnodes.toctree()
tocnode['includefiles'] = docnames
tocnode['maxdepth'] = -1
tocnode['glob'] = None
tocnode['entries'] = [(None, docname) for docname in docnames]
tocnode = autosummary_toc('', '', tocnode)
return warnings + [node] + [tocnode]
else:
return warnings + [node]
def get_autosummary(names, state, no_signatures=False):
"""
Generate a proper table node for autosummary:: directive.
Parameters
----------
names : list of str
Names of Python objects to be imported and added to the table.
document : document
Docutils document object
"""
document = state.document
real_names = {}
warnings = []
prefixes = ['']
prefixes.insert(0, document.settings.env.currmodule)
table = nodes.table('')
group = nodes.tgroup('', cols=2)
table.append(group)
group.append(nodes.colspec('', colwidth=10))
group.append(nodes.colspec('', colwidth=90))
body = nodes.tbody('')
group.append(body)
def append_row(*column_texts):
row = nodes.row('')
for text in column_texts:
node = nodes.paragraph('')
vl = ViewList()
vl.append(text, '<autosummary>')
state.nested_parse(vl, 0, node)
try:
if isinstance(node[0], nodes.paragraph):
node = node[0]
except IndexError:
pass
row.append(nodes.entry('', node))
body.append(row)
for name in names:
try:
obj, real_name = import_by_name(name, prefixes=prefixes)
except ImportError:
warnings.append(document.reporter.warning(
'failed to import %s' % name))
append_row(":obj:`%s`" % name, "")
continue
real_names[name] = real_name
doc = get_doc_object(obj)
if doc['Summary']:
title = " ".join(doc['Summary'])
else:
title = ""
col1 = u":obj:`%s <%s>`" % (name, real_name)
if doc['Signature']:
sig = re.sub('^[^(\[]*', '', doc['Signature'].strip())
if '=' in sig:
# abbreviate optional arguments
sig = re.sub(r', ([a-zA-Z0-9_]+)=', r'[, \1=', sig, count=1)
sig = re.sub(r'\(([a-zA-Z0-9_]+)=', r'([\1=', sig, count=1)
sig = re.sub(r'=[^,)]+,', ',', sig)
sig = re.sub(r'=[^,)]+\)$', '])', sig)
# shorten long strings
sig = re.sub(r'(\[.{16,16}[^,]*?),.*?\]\)', r'\1, ...])', sig)
else:
sig = re.sub(r'(\(.{16,16}[^,]*?),.*?\)', r'\1, ...)', sig)
# make signature contain non-breaking spaces
col1 += u"\\ \u00a0" + unicode(sig).replace(u" ", u"\u00a0")
col2 = title
append_row(col1, col2)
return table, warnings, real_names
def import_by_name(name, prefixes=[None]):
"""
Import a Python object that has the given name, under one of the prefixes.
Parameters
----------
name : str
Name of a Python object, eg. 'numpy.ndarray.view'
prefixes : list of (str or None), optional
Prefixes to prepend to the name (None implies no prefix).
The first prefixed name that results to successful import is used.
Returns
-------
obj
The imported object
name
Name of the imported object (useful if `prefixes` was used)
"""
for prefix in prefixes:
try:
if prefix:
prefixed_name = '.'.join([prefix, name])
else:
prefixed_name = name
return _import_by_name(prefixed_name), prefixed_name
except ImportError:
pass
raise ImportError
def _import_by_name(name):
"""Import a Python object given its full name"""
try:
# try first interpret `name` as MODNAME.OBJ
name_parts = name.split('.')
try:
modname = '.'.join(name_parts[:-1])
__import__(modname)
return getattr(sys.modules[modname], name_parts[-1])
except (ImportError, IndexError, AttributeError):
pass
# ... then as MODNAME, MODNAME.OBJ1, MODNAME.OBJ1.OBJ2, ...
last_j = 0
modname = None
for j in reversed(range(1, len(name_parts)+1)):
last_j = j
modname = '.'.join(name_parts[:j])
try:
__import__(modname)
except ImportError:
continue
if modname in sys.modules:
break
if last_j < len(name_parts):
obj = sys.modules[modname]
for obj_name in name_parts[last_j:]:
obj = getattr(obj, obj_name)
return obj
else:
return sys.modules[modname]
except (ValueError, ImportError, AttributeError, KeyError), e:
raise ImportError(e)
#------------------------------------------------------------------------------
# :autolink: (smart default role)
#------------------------------------------------------------------------------
def autolink_role(typ, rawtext, etext, lineno, inliner,
options={}, content=[]):
"""
Smart linking role.
Expands to ":obj:`text`" if `text` is an object that can be imported;
otherwise expands to "*text*".
"""
r = sphinx.roles.xfileref_role('obj', rawtext, etext, lineno, inliner,
options, content)
pnode = r[0][0]
prefixes = [None]
#prefixes.insert(0, inliner.document.settings.env.currmodule)
try:
obj, name = import_by_name(pnode['reftarget'], prefixes)
except ImportError:
content = pnode[0]
r[0][0] = nodes.emphasis(rawtext, content[0].astext(),
classes=content['classes'])
return r
@@ -1,219 +0,0 @@
#!/usr/bin/env python
r"""
autosummary_generate.py OPTIONS FILES
Generate automatic RST source files for items referred to in
autosummary:: directives.
Each generated RST file contains a single auto*:: directive which
extracts the docstring of the referred item.
Example Makefile rule::
generate:
./ext/autosummary_generate.py -o source/generated source/*.rst
"""
import glob, re, inspect, os, optparse, pydoc
from autosummary import import_by_name
try:
from phantom_import import import_phantom_module
except ImportError:
import_phantom_module = lambda x: x
def main():
p = optparse.OptionParser(__doc__.strip())
p.add_option("-p", "--phantom", action="store", type="string",
dest="phantom", default=None,
help="Phantom import modules from a file")
p.add_option("-o", "--output-dir", action="store", type="string",
dest="output_dir", default=None,
help=("Write all output files to the given directory (instead "
"of writing them as specified in the autosummary:: "
"directives)"))
options, args = p.parse_args()
if len(args) == 0:
p.error("wrong number of arguments")
if options.phantom and os.path.isfile(options.phantom):
import_phantom_module(options.phantom)
# read
names = {}
for name, loc in get_documented(args).items():
for (filename, sec_title, keyword, toctree) in loc:
if toctree is not None:
path = os.path.join(os.path.dirname(filename), toctree)
names[name] = os.path.abspath(path)
# write
for name, path in sorted(names.items()):
if options.output_dir is not None:
path = options.output_dir
if not os.path.isdir(path):
os.makedirs(path)
try:
obj, name = import_by_name(name)
except ImportError, e:
print "Failed to import '%s': %s" % (name, e)
continue
fn = os.path.join(path, '%s.rst' % name)
if os.path.exists(fn):
# skip
continue
f = open(fn, 'w')
try:
f.write('%s\n%s\n\n' % (name, '='*len(name)))
if inspect.isclass(obj):
if issubclass(obj, Exception):
f.write(format_modulemember(name, 'autoexception'))
else:
f.write(format_modulemember(name, 'autoclass'))
elif inspect.ismodule(obj):
f.write(format_modulemember(name, 'automodule'))
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
f.write(format_classmember(name, 'automethod'))
elif callable(obj):
f.write(format_modulemember(name, 'autofunction'))
elif hasattr(obj, '__get__'):
f.write(format_classmember(name, 'autoattribute'))
else:
f.write(format_modulemember(name, 'autofunction'))
finally:
f.close()
def format_modulemember(name, directive):
parts = name.split('.')
mod, name = '.'.join(parts[:-1]), parts[-1]
return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
def format_classmember(name, directive):
parts = name.split('.')
mod, name = '.'.join(parts[:-2]), '.'.join(parts[-2:])
return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name)
def get_documented(filenames):
"""
Find out what items are documented in source/*.rst
See `get_documented_in_lines`.
"""
documented = {}
for filename in filenames:
f = open(filename, 'r')
lines = f.read().splitlines()
documented.update(get_documented_in_lines(lines, filename=filename))
f.close()
return documented
def get_documented_in_docstring(name, module=None, filename=None):
"""
Find out what items are documented in the given object's docstring.
See `get_documented_in_lines`.
"""
try:
obj, real_name = import_by_name(name)
lines = pydoc.getdoc(obj).splitlines()
return get_documented_in_lines(lines, module=name, filename=filename)
except AttributeError:
pass
except ImportError, e:
print "Failed to import '%s': %s" % (name, e)
return {}
def get_documented_in_lines(lines, module=None, filename=None):
"""
Find out what items are documented in the given lines
Returns
-------
documented : dict of list of (filename, title, keyword, toctree)
Dictionary whose keys are documented names of objects.
The value is a list of locations where the object was documented.
Each location is a tuple of filename, the current section title,
the name of the directive, and the value of the :toctree: argument
(if present) of the directive.
"""
title_underline_re = re.compile("^[-=*_^#]{3,}\s*$")
autodoc_re = re.compile(".. auto(function|method|attribute|class|exception|module)::\s*([A-Za-z0-9_.]+)\s*$")
autosummary_re = re.compile(r'^\.\.\s+autosummary::\s*')
module_re = re.compile(r'^\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
autosummary_item_re = re.compile(r'^\s+([_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?')
toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
documented = {}
current_title = []
last_line = None
toctree = None
current_module = module
in_autosummary = False
for line in lines:
try:
if in_autosummary:
m = toctree_arg_re.match(line)
if m:
toctree = m.group(1)
continue
if line.strip().startswith(':'):
continue # skip options
m = autosummary_item_re.match(line)
if m:
name = m.group(1).strip()
if current_module and not name.startswith(current_module + '.'):
name = "%s.%s" % (current_module, name)
documented.setdefault(name, []).append(
(filename, current_title, 'autosummary', toctree))
continue
if line.strip() == '':
continue
in_autosummary = False
m = autosummary_re.match(line)
if m:
in_autosummary = True
continue
m = autodoc_re.search(line)
if m:
name = m.group(2).strip()
if m.group(1) == "module":
current_module = name
documented.update(get_documented_in_docstring(
name, filename=filename))
elif current_module and not name.startswith(current_module+'.'):
name = "%s.%s" % (current_module, name)
documented.setdefault(name, []).append(
(filename, current_title, "auto" + m.group(1), None))
continue
m = title_underline_re.match(line)
if m and last_line:
current_title = last_line.strip()
continue
m = module_re.match(line)
if m:
current_module = m.group(2)
continue
finally:
last_line = line
return documented
if __name__ == "__main__":
main()
-158
View File
@@ -1,158 +0,0 @@
from cStringIO import StringIO
import compiler
import inspect
import textwrap
import tokenize
from compiler_unparse import unparse
class Comment(object):
""" A comment block.
"""
is_comment = True
def __init__(self, start_lineno, end_lineno, text):
# int : The first line number in the block. 1-indexed.
self.start_lineno = start_lineno
# int : The last line number. Inclusive!
self.end_lineno = end_lineno
# str : The text block including '#' character but not any leading spaces.
self.text = text
def add(self, string, start, end, line):
""" Add a new comment line.
"""
self.start_lineno = min(self.start_lineno, start[0])
self.end_lineno = max(self.end_lineno, end[0])
self.text += string
def __repr__(self):
return '%s(%r, %r, %r)' % (self.__class__.__name__, self.start_lineno,
self.end_lineno, self.text)
class NonComment(object):
""" A non-comment block of code.
"""
is_comment = False
def __init__(self, start_lineno, end_lineno):
self.start_lineno = start_lineno
self.end_lineno = end_lineno
def add(self, string, start, end, line):
""" Add lines to the block.
"""
if string.strip():
# Only add if not entirely whitespace.
self.start_lineno = min(self.start_lineno, start[0])
self.end_lineno = max(self.end_lineno, end[0])
def __repr__(self):
return '%s(%r, %r)' % (self.__class__.__name__, self.start_lineno,
self.end_lineno)
class CommentBlocker(object):
""" Pull out contiguous comment blocks.
"""
def __init__(self):
# Start with a dummy.
self.current_block = NonComment(0, 0)
# All of the blocks seen so far.
self.blocks = []
# The index mapping lines of code to their associated comment blocks.
self.index = {}
def process_file(self, file):
""" Process a file object.
"""
for token in tokenize.generate_tokens(file.next):
self.process_token(*token)
self.make_index()
def process_token(self, kind, string, start, end, line):
""" Process a single token.
"""
if self.current_block.is_comment:
if kind == tokenize.COMMENT:
self.current_block.add(string, start, end, line)
else:
self.new_noncomment(start[0], end[0])
else:
if kind == tokenize.COMMENT:
self.new_comment(string, start, end, line)
else:
self.current_block.add(string, start, end, line)
def new_noncomment(self, start_lineno, end_lineno):
""" We are transitioning from a noncomment to a comment.
"""
block = NonComment(start_lineno, end_lineno)
self.blocks.append(block)
self.current_block = block
def new_comment(self, string, start, end, line):
""" Possibly add a new comment.
Only adds a new comment if this comment is the only thing on the line.
Otherwise, it extends the noncomment block.
"""
prefix = line[:start[1]]
if prefix.strip():
# Oops! Trailing comment, not a comment block.
self.current_block.add(string, start, end, line)
else:
# A comment block.
block = Comment(start[0], end[0], string)
self.blocks.append(block)
self.current_block = block
def make_index(self):
""" Make the index mapping lines of actual code to their associated
prefix comments.
"""
for prev, block in zip(self.blocks[:-1], self.blocks[1:]):
if not block.is_comment:
self.index[block.start_lineno] = prev
def search_for_comment(self, lineno, default=None):
""" Find the comment block just before the given line number.
Returns None (or the specified default) if there is no such block.
"""
if not self.index:
self.make_index()
block = self.index.get(lineno, None)
text = getattr(block, 'text', default)
return text
def strip_comment_marker(text):
""" Strip # markers at the front of a block of comment text.
"""
lines = []
for line in text.splitlines():
lines.append(line.lstrip('#'))
text = textwrap.dedent('\n'.join(lines))
return text
def get_class_traits(klass):
""" Yield all of the documentation for trait definitions on a class object.
"""
# FIXME: gracefully handle errors here or in the caller?
source = inspect.getsource(klass)
cb = CommentBlocker()
cb.process_file(StringIO(source))
mod_ast = compiler.parse(source)
class_ast = mod_ast.node.nodes[0]
for node in class_ast.code.nodes:
# FIXME: handle other kinds of assignments?
if isinstance(node, compiler.ast.Assign):
name = node.nodes[0].name
rhs = unparse(node.expr).strip()
doc = strip_comment_marker(cb.search_for_comment(node.lineno, default=''))
yield name, rhs, doc
-860
View File
@@ -1,860 +0,0 @@
""" Turn compiler.ast structures back into executable python code.
The unparse method takes a compiler.ast tree and transforms it back into
valid python code. It is incomplete and currently only works for
import statements, function calls, function definitions, assignments, and
basic expressions.
Inspired by python-2.5-svn/Demo/parser/unparse.py
fixme: We may want to move to using _ast trees because the compiler for
them is about 6 times faster than compiler.compile.
"""
import sys
import cStringIO
from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add
def unparse(ast, single_line_functions=False):
s = cStringIO.StringIO()
UnparseCompilerAst(ast, s, single_line_functions)
return s.getvalue().lstrip()
op_precedence = { 'compiler.ast.Power':3, 'compiler.ast.Mul':2, 'compiler.ast.Div':2,
'compiler.ast.Add':1, 'compiler.ast.Sub':1 }
class UnparseCompilerAst:
""" Methods in this class recursively traverse an AST and
output source code for the abstract syntax; original formatting
is disregarged.
"""
#########################################################################
# object interface.
#########################################################################
def __init__(self, tree, file = sys.stdout, single_line_functions=False):
""" Unparser(tree, file=sys.stdout) -> None.
Print the source for tree to file.
"""
self.f = file
self._single_func = single_line_functions
self._do_indent = True
self._indent = 0
self._dispatch(tree)
self._write("\n")
self.f.flush()
#########################################################################
# Unparser private interface.
#########################################################################
### format, output, and dispatch methods ################################
def _fill(self, text = ""):
"Indent a piece of text, according to the current indentation level"
if self._do_indent:
self._write("\n"+" "*self._indent + text)
else:
self._write(text)
def _write(self, text):
"Append a piece of text to the current line."
self.f.write(text)
def _enter(self):
"Print ':', and increase the indentation."
self._write(": ")
self._indent += 1
def _leave(self):
"Decrease the indentation level."
self._indent -= 1
def _dispatch(self, tree):
"_dispatcher function, _dispatching tree type T to method _T."
if isinstance(tree, list):
for t in tree:
self._dispatch(t)
return
meth = getattr(self, "_"+tree.__class__.__name__)
if tree.__class__.__name__ == 'NoneType' and not self._do_indent:
return
meth(tree)
#########################################################################
# compiler.ast unparsing methods.
#
# There should be one method per concrete grammar type. They are
# organized in alphabetical order.
#########################################################################
def _Add(self, t):
self.__binary_op(t, '+')
def _And(self, t):
self._write(" (")
for i, node in enumerate(t.nodes):
self._dispatch(node)
if i != len(t.nodes)-1:
self._write(") and (")
self._write(")")
def _AssAttr(self, t):
""" Handle assigning an attribute of an object
"""
self._dispatch(t.expr)
self._write('.'+t.attrname)
def _Assign(self, t):
""" Expression Assignment such as "a = 1".
This only handles assignment in expressions. Keyword assignment
is handled separately.
"""
self._fill()
for target in t.nodes:
self._dispatch(target)
self._write(" = ")
self._dispatch(t.expr)
if not self._do_indent:
self._write('; ')
def _AssName(self, t):
""" Name on left hand side of expression.
Treat just like a name on the right side of an expression.
"""
self._Name(t)
def _AssTuple(self, t):
""" Tuple on left hand side of an expression.
"""
# _write each elements, separated by a comma.
for element in t.nodes[:-1]:
self._dispatch(element)
self._write(", ")
# Handle the last one without writing comma
last_element = t.nodes[-1]
self._dispatch(last_element)
def _AugAssign(self, t):
""" +=,-=,*=,/=,**=, etc. operations
"""
self._fill()
self._dispatch(t.node)
self._write(' '+t.op+' ')
self._dispatch(t.expr)
if not self._do_indent:
self._write(';')
def _Bitand(self, t):
""" Bit and operation.
"""
for i, node in enumerate(t.nodes):
self._write("(")
self._dispatch(node)
self._write(")")
if i != len(t.nodes)-1:
self._write(" & ")
def _Bitor(self, t):
""" Bit or operation
"""
for i, node in enumerate(t.nodes):
self._write("(")
self._dispatch(node)
self._write(")")
if i != len(t.nodes)-1:
self._write(" | ")
def _CallFunc(self, t):
""" Function call.
"""
self._dispatch(t.node)
self._write("(")
comma = False
for e in t.args:
if comma: self._write(", ")
else: comma = True
self._dispatch(e)
if t.star_args:
if comma: self._write(", ")
else: comma = True
self._write("*")
self._dispatch(t.star_args)
if t.dstar_args:
if comma: self._write(", ")
else: comma = True
self._write("**")
self._dispatch(t.dstar_args)
self._write(")")
def _Compare(self, t):
self._dispatch(t.expr)
for op, expr in t.ops:
self._write(" " + op + " ")
self._dispatch(expr)
def _Const(self, t):
""" A constant value such as an integer value, 3, or a string, "hello".
"""
self._dispatch(t.value)
def _Decorators(self, t):
""" Handle function decorators (eg. @has_units)
"""
for node in t.nodes:
self._dispatch(node)
def _Dict(self, t):
self._write("{")
for i, (k, v) in enumerate(t.items):
self._dispatch(k)
self._write(": ")
self._dispatch(v)
if i < len(t.items)-1:
self._write(", ")
self._write("}")
def _Discard(self, t):
""" Node for when return value is ignored such as in "foo(a)".
"""
self._fill()
self._dispatch(t.expr)
def _Div(self, t):
self.__binary_op(t, '/')
def _Ellipsis(self, t):
self._write("...")
def _From(self, t):
""" Handle "from xyz import foo, bar as baz".
"""
# fixme: Are From and ImportFrom handled differently?
self._fill("from ")
self._write(t.modname)
self._write(" import ")
for i, (name,asname) in enumerate(t.names):
if i != 0:
self._write(", ")
self._write(name)
if asname is not None:
self._write(" as "+asname)
def _Function(self, t):
""" Handle function definitions
"""
if t.decorators is not None:
self._fill("@")
self._dispatch(t.decorators)
self._fill("def "+t.name + "(")
defaults = [None] * (len(t.argnames) - len(t.defaults)) + list(t.defaults)
for i, arg in enumerate(zip(t.argnames, defaults)):
self._write(arg[0])
if arg[1] is not None:
self._write('=')
self._dispatch(arg[1])
if i < len(t.argnames)-1:
self._write(', ')
self._write(")")
if self._single_func:
self._do_indent = False
self._enter()
self._dispatch(t.code)
self._leave()
self._do_indent = True
def _Getattr(self, t):
""" Handle getting an attribute of an object
"""
if isinstance(t.expr, (Div, Mul, Sub, Add)):
self._write('(')
self._dispatch(t.expr)
self._write(')')
else:
self._dispatch(t.expr)
self._write('.'+t.attrname)
def _If(self, t):
self._fill()
for i, (compare,code) in enumerate(t.tests):
if i == 0:
self._write("if ")
else:
self._write("elif ")
self._dispatch(compare)
self._enter()
self._fill()
self._dispatch(code)
self._leave()
self._write("\n")
if t.else_ is not None:
self._write("else")
self._enter()
self._fill()
self._dispatch(t.else_)
self._leave()
self._write("\n")
def _IfExp(self, t):
self._dispatch(t.then)
self._write(" if ")
self._dispatch(t.test)
if t.else_ is not None:
self._write(" else (")
self._dispatch(t.else_)
self._write(")")
def _Import(self, t):
""" Handle "import xyz.foo".
"""
self._fill("import ")
for i, (name,asname) in enumerate(t.names):
if i != 0:
self._write(", ")
self._write(name)
if asname is not None:
self._write(" as "+asname)
def _Keyword(self, t):
""" Keyword value assignment within function calls and definitions.
"""
self._write(t.name)
self._write("=")
self._dispatch(t.expr)
def _List(self, t):
self._write("[")
for i,node in enumerate(t.nodes):
self._dispatch(node)
if i < len(t.nodes)-1:
self._write(", ")
self._write("]")
def _Module(self, t):
if t.doc is not None:
self._dispatch(t.doc)
self._dispatch(t.node)
def _Mul(self, t):
self.__binary_op(t, '*')
def _Name(self, t):
self._write(t.name)
def _NoneType(self, t):
self._write("None")
def _Not(self, t):
self._write('not (')
self._dispatch(t.expr)
self._write(')')
def _Or(self, t):
self._write(" (")
for i, node in enumerate(t.nodes):
self._dispatch(node)
if i != len(t.nodes)-1:
self._write(") or (")
self._write(")")
def _Pass(self, t):
self._write("pass\n")
def _Printnl(self, t):
self._fill("print ")
if t.dest:
self._write(">> ")
self._dispatch(t.dest)
self._write(", ")
comma = False
for node in t.nodes:
if comma: self._write(', ')
else: comma = True
self._dispatch(node)
def _Power(self, t):
self.__binary_op(t, '**')
def _Return(self, t):
self._fill("return ")
if t.value:
if isinstance(t.value, Tuple):
text = ', '.join([ name.name for name in t.value.asList() ])
self._write(text)
else:
self._dispatch(t.value)
if not self._do_indent:
self._write('; ')
def _Slice(self, t):
self._dispatch(t.expr)
self._write("[")
if t.lower:
self._dispatch(t.lower)
self._write(":")
if t.upper:
self._dispatch(t.upper)
#if t.step:
# self._write(":")
# self._dispatch(t.step)
self._write("]")
def _Sliceobj(self, t):
for i, node in enumerate(t.nodes):
if i != 0:
self._write(":")
if not (isinstance(node, Const) and node.value is None):
self._dispatch(node)
def _Stmt(self, tree):
for node in tree.nodes:
self._dispatch(node)
def _Sub(self, t):
self.__binary_op(t, '-')
def _Subscript(self, t):
self._dispatch(t.expr)
self._write("[")
for i, value in enumerate(t.subs):
if i != 0:
self._write(",")
self._dispatch(value)
self._write("]")
def _TryExcept(self, t):
self._fill("try")
self._enter()
self._dispatch(t.body)
self._leave()
for handler in t.handlers:
self._fill('except ')
self._dispatch(handler[0])
if handler[1] is not None:
self._write(', ')
self._dispatch(handler[1])
self._enter()
self._dispatch(handler[2])
self._leave()
if t.else_:
self._fill("else")
self._enter()
self._dispatch(t.else_)
self._leave()
def _Tuple(self, t):
if not t.nodes:
# Empty tuple.
self._write("()")
else:
self._write("(")
# _write each elements, separated by a comma.
for element in t.nodes[:-1]:
self._dispatch(element)
self._write(", ")
# Handle the last one without writing comma
last_element = t.nodes[-1]
self._dispatch(last_element)
self._write(")")
def _UnaryAdd(self, t):
self._write("+")
self._dispatch(t.expr)
def _UnarySub(self, t):
self._write("-")
self._dispatch(t.expr)
def _With(self, t):
self._fill('with ')
self._dispatch(t.expr)
if t.vars:
self._write(' as ')
self._dispatch(t.vars.name)
self._enter()
self._dispatch(t.body)
self._leave()
self._write('\n')
def _int(self, t):
self._write(repr(t))
def __binary_op(self, t, symbol):
# Check if parenthesis are needed on left side and then dispatch
has_paren = False
left_class = str(t.left.__class__)
if (left_class in op_precedence.keys() and
op_precedence[left_class] < op_precedence[str(t.__class__)]):
has_paren = True
if has_paren:
self._write('(')
self._dispatch(t.left)
if has_paren:
self._write(')')
# Write the appropriate symbol for operator
self._write(symbol)
# Check if parenthesis are needed on the right side and then dispatch
has_paren = False
right_class = str(t.right.__class__)
if (right_class in op_precedence.keys() and
op_precedence[right_class] < op_precedence[str(t.__class__)]):
has_paren = True
if has_paren:
self._write('(')
self._dispatch(t.right)
if has_paren:
self._write(')')
def _float(self, t):
# if t is 0.1, str(t)->'0.1' while repr(t)->'0.1000000000001'
# We prefer str here.
self._write(str(t))
def _str(self, t):
self._write(repr(t))
def _tuple(self, t):
self._write(str(t))
#########################################################################
# These are the methods from the _ast modules unparse.
#
# As our needs to handle more advanced code increase, we may want to
# modify some of the methods below so that they work for compiler.ast.
#########################################################################
# # stmt
# def _Expr(self, tree):
# self._fill()
# self._dispatch(tree.value)
#
# def _Import(self, t):
# self._fill("import ")
# first = True
# for a in t.names:
# if first:
# first = False
# else:
# self._write(", ")
# self._write(a.name)
# if a.asname:
# self._write(" as "+a.asname)
#
## def _ImportFrom(self, t):
## self._fill("from ")
## self._write(t.module)
## self._write(" import ")
## for i, a in enumerate(t.names):
## if i == 0:
## self._write(", ")
## self._write(a.name)
## if a.asname:
## self._write(" as "+a.asname)
## # XXX(jpe) what is level for?
##
#
# def _Break(self, t):
# self._fill("break")
#
# def _Continue(self, t):
# self._fill("continue")
#
# def _Delete(self, t):
# self._fill("del ")
# self._dispatch(t.targets)
#
# def _Assert(self, t):
# self._fill("assert ")
# self._dispatch(t.test)
# if t.msg:
# self._write(", ")
# self._dispatch(t.msg)
#
# def _Exec(self, t):
# self._fill("exec ")
# self._dispatch(t.body)
# if t.globals:
# self._write(" in ")
# self._dispatch(t.globals)
# if t.locals:
# self._write(", ")
# self._dispatch(t.locals)
#
# def _Print(self, t):
# self._fill("print ")
# do_comma = False
# if t.dest:
# self._write(">>")
# self._dispatch(t.dest)
# do_comma = True
# for e in t.values:
# if do_comma:self._write(", ")
# else:do_comma=True
# self._dispatch(e)
# if not t.nl:
# self._write(",")
#
# def _Global(self, t):
# self._fill("global")
# for i, n in enumerate(t.names):
# if i != 0:
# self._write(",")
# self._write(" " + n)
#
# def _Yield(self, t):
# self._fill("yield")
# if t.value:
# self._write(" (")
# self._dispatch(t.value)
# self._write(")")
#
# def _Raise(self, t):
# self._fill('raise ')
# if t.type:
# self._dispatch(t.type)
# if t.inst:
# self._write(", ")
# self._dispatch(t.inst)
# if t.tback:
# self._write(", ")
# self._dispatch(t.tback)
#
#
# def _TryFinally(self, t):
# self._fill("try")
# self._enter()
# self._dispatch(t.body)
# self._leave()
#
# self._fill("finally")
# self._enter()
# self._dispatch(t.finalbody)
# self._leave()
#
# def _excepthandler(self, t):
# self._fill("except ")
# if t.type:
# self._dispatch(t.type)
# if t.name:
# self._write(", ")
# self._dispatch(t.name)
# self._enter()
# self._dispatch(t.body)
# self._leave()
#
# def _ClassDef(self, t):
# self._write("\n")
# self._fill("class "+t.name)
# if t.bases:
# self._write("(")
# for a in t.bases:
# self._dispatch(a)
# self._write(", ")
# self._write(")")
# self._enter()
# self._dispatch(t.body)
# self._leave()
#
# def _FunctionDef(self, t):
# self._write("\n")
# for deco in t.decorators:
# self._fill("@")
# self._dispatch(deco)
# self._fill("def "+t.name + "(")
# self._dispatch(t.args)
# self._write(")")
# self._enter()
# self._dispatch(t.body)
# self._leave()
#
# def _For(self, t):
# self._fill("for ")
# self._dispatch(t.target)
# self._write(" in ")
# self._dispatch(t.iter)
# self._enter()
# self._dispatch(t.body)
# self._leave()
# if t.orelse:
# self._fill("else")
# self._enter()
# self._dispatch(t.orelse)
# self._leave
#
# def _While(self, t):
# self._fill("while ")
# self._dispatch(t.test)
# self._enter()
# self._dispatch(t.body)
# self._leave()
# if t.orelse:
# self._fill("else")
# self._enter()
# self._dispatch(t.orelse)
# self._leave
#
# # expr
# def _Str(self, tree):
# self._write(repr(tree.s))
##
# def _Repr(self, t):
# self._write("`")
# self._dispatch(t.value)
# self._write("`")
#
# def _Num(self, t):
# self._write(repr(t.n))
#
# def _ListComp(self, t):
# self._write("[")
# self._dispatch(t.elt)
# for gen in t.generators:
# self._dispatch(gen)
# self._write("]")
#
# def _GeneratorExp(self, t):
# self._write("(")
# self._dispatch(t.elt)
# for gen in t.generators:
# self._dispatch(gen)
# self._write(")")
#
# def _comprehension(self, t):
# self._write(" for ")
# self._dispatch(t.target)
# self._write(" in ")
# self._dispatch(t.iter)
# for if_clause in t.ifs:
# self._write(" if ")
# self._dispatch(if_clause)
#
# def _IfExp(self, t):
# self._dispatch(t.body)
# self._write(" if ")
# self._dispatch(t.test)
# if t.orelse:
# self._write(" else ")
# self._dispatch(t.orelse)
#
# unop = {"Invert":"~", "Not": "not", "UAdd":"+", "USub":"-"}
# def _UnaryOp(self, t):
# self._write(self.unop[t.op.__class__.__name__])
# self._write("(")
# self._dispatch(t.operand)
# self._write(")")
#
# binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%",
# "LShift":">>", "RShift":"<<", "BitOr":"|", "BitXor":"^", "BitAnd":"&",
# "FloorDiv":"//", "Pow": "**"}
# def _BinOp(self, t):
# self._write("(")
# self._dispatch(t.left)
# self._write(")" + self.binop[t.op.__class__.__name__] + "(")
# self._dispatch(t.right)
# self._write(")")
#
# boolops = {_ast.And: 'and', _ast.Or: 'or'}
# def _BoolOp(self, t):
# self._write("(")
# self._dispatch(t.values[0])
# for v in t.values[1:]:
# self._write(" %s " % self.boolops[t.op.__class__])
# self._dispatch(v)
# self._write(")")
#
# def _Attribute(self,t):
# self._dispatch(t.value)
# self._write(".")
# self._write(t.attr)
#
## def _Call(self, t):
## self._dispatch(t.func)
## self._write("(")
## comma = False
## for e in t.args:
## if comma: self._write(", ")
## else: comma = True
## self._dispatch(e)
## for e in t.keywords:
## if comma: self._write(", ")
## else: comma = True
## self._dispatch(e)
## if t.starargs:
## if comma: self._write(", ")
## else: comma = True
## self._write("*")
## self._dispatch(t.starargs)
## if t.kwargs:
## if comma: self._write(", ")
## else: comma = True
## self._write("**")
## self._dispatch(t.kwargs)
## self._write(")")
#
# # slice
# def _Index(self, t):
# self._dispatch(t.value)
#
# def _ExtSlice(self, t):
# for i, d in enumerate(t.dims):
# if i != 0:
# self._write(': ')
# self._dispatch(d)
#
# # others
# def _arguments(self, t):
# first = True
# nonDef = len(t.args)-len(t.defaults)
# for a in t.args[0:nonDef]:
# if first:first = False
# else: self._write(", ")
# self._dispatch(a)
# for a,d in zip(t.args[nonDef:], t.defaults):
# if first:first = False
# else: self._write(", ")
# self._dispatch(a),
# self._write("=")
# self._dispatch(d)
# if t.vararg:
# if first:first = False
# else: self._write(", ")
# self._write("*"+t.vararg)
# if t.kwarg:
# if first:first = False
# else: self._write(", ")
# self._write("**"+t.kwarg)
#
## def _keyword(self, t):
## self._write(t.arg)
## self._write("=")
## self._dispatch(t.value)
#
# def _Lambda(self, t):
# self._write("lambda ")
# self._dispatch(t.args)
# self._write(": ")
# self._dispatch(t.body)
-497
View File
@@ -1,497 +0,0 @@
"""Extract reference documentation from the NumPy source tree.
"""
import inspect
import textwrap
import re
import pydoc
from StringIO import StringIO
from warnings import warn
4
class Reader(object):
"""A line-based string reader.
"""
def __init__(self, data):
"""
Parameters
----------
data : str
String with lines separated by '\n'.
"""
if isinstance(data,list):
self._str = data
else:
self._str = data.split('\n') # store string as list of lines
self.reset()
def __getitem__(self, n):
return self._str[n]
def reset(self):
self._l = 0 # current line nr
def read(self):
if not self.eof():
out = self[self._l]
self._l += 1
return out
else:
return ''
def seek_next_non_empty_line(self):
for l in self[self._l:]:
if l.strip():
break
else:
self._l += 1
def eof(self):
return self._l >= len(self._str)
def read_to_condition(self, condition_func):
start = self._l
for line in self[start:]:
if condition_func(line):
return self[start:self._l]
self._l += 1
if self.eof():
return self[start:self._l+1]
return []
def read_to_next_empty_line(self):
self.seek_next_non_empty_line()
def is_empty(line):
return not line.strip()
return self.read_to_condition(is_empty)
def read_to_next_unindented_line(self):
def is_unindented(line):
return (line.strip() and (len(line.lstrip()) == len(line)))
return self.read_to_condition(is_unindented)
def peek(self,n=0):
if self._l + n < len(self._str):
return self[self._l + n]
else:
return ''
def is_empty(self):
return not ''.join(self._str).strip()
class NumpyDocString(object):
def __init__(self,docstring):
docstring = textwrap.dedent(docstring).split('\n')
self._doc = Reader(docstring)
self._parsed_data = {
'Signature': '',
'Summary': [''],
'Extended Summary': [],
'Parameters': [],
'Returns': [],
'Raises': [],
'Warns': [],
'Other Parameters': [],
'Attributes': [],
'Methods': [],
'See Also': [],
'Notes': [],
'Warnings': [],
'References': '',
'Examples': '',
'index': {}
}
self._parse()
def __getitem__(self,key):
return self._parsed_data[key]
def __setitem__(self,key,val):
if not self._parsed_data.has_key(key):
warn("Unknown section %s" % key)
else:
self._parsed_data[key] = val
def _is_at_section(self):
self._doc.seek_next_non_empty_line()
if self._doc.eof():
return False
l1 = self._doc.peek().strip() # e.g. Parameters
if l1.startswith('.. index::'):
return True
l2 = self._doc.peek(1).strip() # ---------- or ==========
return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1))
def _strip(self,doc):
i = 0
j = 0
for i,line in enumerate(doc):
if line.strip(): break
for j,line in enumerate(doc[::-1]):
if line.strip(): break
return doc[i:len(doc)-j]
def _read_to_next_section(self):
section = self._doc.read_to_next_empty_line()
while not self._is_at_section() and not self._doc.eof():
if not self._doc.peek(-1).strip(): # previous line was empty
section += ['']
section += self._doc.read_to_next_empty_line()
return section
def _read_sections(self):
while not self._doc.eof():
data = self._read_to_next_section()
name = data[0].strip()
if name.startswith('..'): # index section
yield name, data[1:]
elif len(data) < 2:
yield StopIteration
else:
yield name, self._strip(data[2:])
def _parse_param_list(self,content):
r = Reader(content)
params = []
while not r.eof():
header = r.read().strip()
if ' : ' in header:
arg_name, arg_type = header.split(' : ')[:2]
else:
arg_name, arg_type = header, ''
desc = r.read_to_next_unindented_line()
desc = dedent_lines(desc)
params.append((arg_name,arg_type,desc))
return params
_name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
def _parse_see_also(self, content):
"""
func_name : Descriptive text
continued text
another_func_name : Descriptive text
func_name1, func_name2, :meth:`func_name`, func_name3
"""
items = []
def parse_item_name(text):
"""Match ':role:`name`' or 'name'"""
m = self._name_rgx.match(text)
if m:
g = m.groups()
if g[1] is None:
return g[3], None
else:
return g[2], g[1]
raise ValueError("%s is not a item name" % text)
def push_item(name, rest):
if not name:
return
name, role = parse_item_name(name)
items.append((name, list(rest), role))
del rest[:]
current_func = None
rest = []
for line in content:
if not line.strip(): continue
m = self._name_rgx.match(line)
if m and line[m.end():].strip().startswith(':'):
push_item(current_func, rest)
current_func, line = line[:m.end()], line[m.end():]
rest = [line.split(':', 1)[1].strip()]
if not rest[0]:
rest = []
elif not line.startswith(' '):
push_item(current_func, rest)
current_func = None
if ',' in line:
for func in line.split(','):
push_item(func, [])
elif line.strip():
current_func = line
elif current_func is not None:
rest.append(line.strip())
push_item(current_func, rest)
return items
def _parse_index(self, section, content):
"""
.. index: default
:refguide: something, else, and more
"""
def strip_each_in(lst):
return [s.strip() for s in lst]
out = {}
section = section.split('::')
if len(section) > 1:
out['default'] = strip_each_in(section[1].split(','))[0]
for line in content:
line = line.split(':')
if len(line) > 2:
out[line[1]] = strip_each_in(line[2].split(','))
return out
def _parse_summary(self):
"""Grab signature (if given) and summary"""
if self._is_at_section():
return
summary = self._doc.read_to_next_empty_line()
summary_str = " ".join([s.strip() for s in summary]).strip()
if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
self['Signature'] = summary_str
if not self._is_at_section():
self['Summary'] = self._doc.read_to_next_empty_line()
else:
self['Summary'] = summary
if not self._is_at_section():
self['Extended Summary'] = self._read_to_next_section()
def _parse(self):
self._doc.reset()
self._parse_summary()
for (section,content) in self._read_sections():
if not section.startswith('..'):
section = ' '.join([s.capitalize() for s in section.split(' ')])
if section in ('Parameters', 'Attributes', 'Methods',
'Returns', 'Raises', 'Warns'):
self[section] = self._parse_param_list(content)
elif section.startswith('.. index::'):
self['index'] = self._parse_index(section, content)
elif section == 'See Also':
self['See Also'] = self._parse_see_also(content)
else:
self[section] = content
# string conversion routines
def _str_header(self, name, symbol='-'):
return [name, len(name)*symbol]
def _str_indent(self, doc, indent=4):
out = []
for line in doc:
out += [' '*indent + line]
return out
def _str_signature(self):
if self['Signature']:
return [self['Signature'].replace('*','\*')] + ['']
else:
return ['']
def _str_summary(self):
if self['Summary']:
return self['Summary'] + ['']
else:
return []
def _str_extended_summary(self):
if self['Extended Summary']:
return self['Extended Summary'] + ['']
else:
return []
def _str_param_list(self, name):
out = []
if self[name]:
out += self._str_header(name)
for param,param_type,desc in self[name]:
out += ['%s : %s' % (param, param_type)]
out += self._str_indent(desc)
out += ['']
return out
def _str_section(self, name):
out = []
if self[name]:
out += self._str_header(name)
out += self[name]
out += ['']
return out
def _str_see_also(self, func_role):
if not self['See Also']: return []
out = []
out += self._str_header("See Also")
last_had_desc = True
for func, desc, role in self['See Also']:
if role:
link = ':%s:`%s`' % (role, func)
elif func_role:
link = ':%s:`%s`' % (func_role, func)
else:
link = "`%s`_" % func
if desc or last_had_desc:
out += ['']
out += [link]
else:
out[-1] += ", %s" % link
if desc:
out += self._str_indent([' '.join(desc)])
last_had_desc = True
else:
last_had_desc = False
out += ['']
return out
def _str_index(self):
idx = self['index']
out = []
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
if section == 'default':
continue
out += [' :%s: %s' % (section, ', '.join(references))]
return out
def __str__(self, func_role=''):
out = []
out += self._str_signature()
out += self._str_summary()
out += self._str_extended_summary()
for param_list in ('Parameters','Returns','Raises'):
out += self._str_param_list(param_list)
out += self._str_section('Warnings')
out += self._str_see_also(func_role)
for s in ('Notes','References','Examples'):
out += self._str_section(s)
out += self._str_index()
return '\n'.join(out)
def indent(str,indent=4):
indent_str = ' '*indent
if str is None:
return indent_str
lines = str.split('\n')
return '\n'.join(indent_str + l for l in lines)
def dedent_lines(lines):
"""Deindent a list of lines maximally"""
return textwrap.dedent("\n".join(lines)).split("\n")
def header(text, style='-'):
return text + '\n' + style*len(text) + '\n'
class FunctionDoc(NumpyDocString):
def __init__(self, func, role='func', doc=None):
self._f = func
self._role = role # e.g. "func" or "meth"
if doc is None:
doc = inspect.getdoc(func) or ''
try:
NumpyDocString.__init__(self, doc)
except ValueError, e:
print '*'*78
print "ERROR: '%s' while parsing `%s`" % (e, self._f)
print '*'*78
#print "Docstring follows:"
#print doclines
#print '='*78
if not self['Signature']:
func, func_name = self.get_func()
try:
# try to read signature
argspec = inspect.getargspec(func)
argspec = inspect.formatargspec(*argspec)
argspec = argspec.replace('*','\*')
signature = '%s%s' % (func_name, argspec)
except TypeError, e:
signature = '%s()' % func_name
self['Signature'] = signature
def get_func(self):
func_name = getattr(self._f, '__name__', self.__class__.__name__)
if inspect.isclass(self._f):
func = getattr(self._f, '__call__', self._f.__init__)
else:
func = self._f
return func, func_name
def __str__(self):
out = ''
func, func_name = self.get_func()
signature = self['Signature'].replace('*', '\*')
roles = {'func': 'function',
'meth': 'method'}
if self._role:
if not roles.has_key(self._role):
print "Warning: invalid role %s" % self._role
out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''),
func_name)
out += super(FunctionDoc, self).__str__(func_role=self._role)
return out
class ClassDoc(NumpyDocString):
def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
if not inspect.isclass(cls):
raise ValueError("Initialise using a class. Got %r" % cls)
self._cls = cls
if modulename and not modulename.endswith('.'):
modulename += '.'
self._mod = modulename
self._name = cls.__name__
self._func_doc = func_doc
if doc is None:
doc = pydoc.getdoc(cls)
NumpyDocString.__init__(self, doc)
@property
def methods(self):
return [name for name,func in inspect.getmembers(self._cls)
if not name.startswith('_') and callable(func)]
def __str__(self):
out = ''
out += super(ClassDoc, self).__str__()
out += "\n\n"
#for m in self.methods:
# print "Parsing `%s`" % m
# out += str(self._func_doc(getattr(self._cls,m), 'meth')) + '\n\n'
# out += '.. index::\n single: %s; %s\n\n' % (self._name, m)
return out
-149
View File
@@ -1,149 +0,0 @@
import re, inspect, textwrap, pydoc
import sphinx
from docscrape import NumpyDocString, FunctionDoc, ClassDoc
class SphinxDocString(NumpyDocString):
# string conversion routines
def _str_header(self, name, symbol='`'):
return ['.. rubric:: ' + name, '']
def _str_field_list(self, name):
return [':' + name + ':']
def _str_indent(self, doc, indent=4):
out = []
for line in doc:
out += [' '*indent + line]
return out
def _str_signature(self):
return ['']
if self['Signature']:
return ['``%s``' % self['Signature']] + ['']
else:
return ['']
def _str_summary(self):
return self['Summary'] + ['']
def _str_extended_summary(self):
return self['Extended Summary'] + ['']
def _str_param_list(self, name):
out = []
if self[name]:
out += self._str_field_list(name)
out += ['']
for param,param_type,desc in self[name]:
out += self._str_indent(['**%s** : %s' % (param.strip(),
param_type)])
out += ['']
out += self._str_indent(desc,8)
out += ['']
return out
def _str_section(self, name):
out = []
if self[name]:
out += self._str_header(name)
out += ['']
content = textwrap.dedent("\n".join(self[name])).split("\n")
out += content
out += ['']
return out
def _str_see_also(self, func_role):
out = []
if self['See Also']:
see_also = super(SphinxDocString, self)._str_see_also(func_role)
out = ['.. seealso::', '']
out += self._str_indent(see_also[2:])
return out
def _str_warnings(self):
out = []
if self['Warnings']:
out = ['.. warning::', '']
out += self._str_indent(self['Warnings'])
return out
def _str_index(self):
idx = self['index']
out = []
if len(idx) == 0:
return out
out += ['.. index:: %s' % idx.get('default','')]
for section, references in idx.iteritems():
if section == 'default':
continue
elif section == 'refguide':
out += [' single: %s' % (', '.join(references))]
else:
out += [' %s: %s' % (section, ','.join(references))]
return out
def _str_references(self):
out = []
if self['References']:
out += self._str_header('References')
if isinstance(self['References'], str):
self['References'] = [self['References']]
out.extend(self['References'])
out += ['']
# Latex collects all references to a separate bibliography,
# so we need to insert links to it
if sphinx.__version__ >= 0.6:
out += ['.. only:: latex','']
else:
out += ['.. latexonly::','']
items = []
for line in self['References']:
m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I)
if m:
items.append(m.group(1))
out += [' ' + ", ".join(["[%s]_" % item for item in items]), '']
return out
def __str__(self, indent=0, func_role="obj"):
out = []
out += self._str_signature()
out += self._str_index() + ['']
out += self._str_summary()
out += self._str_extended_summary()
for param_list in ('Parameters', 'Attributes', 'Methods',
'Returns','Raises'):
out += self._str_param_list(param_list)
out += self._str_warnings()
out += self._str_see_also(func_role)
out += self._str_section('Notes')
out += self._str_references()
out += self._str_section('Examples')
out = self._str_indent(out,indent)
return '\n'.join(out)
class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
pass
class SphinxClassDoc(SphinxDocString, ClassDoc):
pass
def get_doc_object(obj, what=None, doc=None):
if what is None:
if inspect.isclass(obj):
what = 'class'
elif inspect.ismodule(obj):
what = 'module'
elif callable(obj):
what = 'function'
else:
what = 'object'
if what == 'class':
return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc)
elif what in ('function', 'method'):
return SphinxFunctionDoc(obj, '', doc=doc)
else:
if doc is None:
doc = pydoc.getdoc(obj)
return SphinxDocString(doc)
-117
View File
@@ -1,117 +0,0 @@
"""
========
numpydoc
========
Sphinx extension that handles docstrings in the Numpy standard format. [1]
It will:
- Convert Parameters etc. sections to field lists.
- Convert See Also section to a See also entry.
- Renumber references.
- Extract the signature from the docstring, if it can't be determined otherwise.
.. [1] http://projects.scipy.org/numpy/wiki/CodingStyleGuidelines#docstring-standard
"""
import os, re, pydoc
from docscrape_sphinx import get_doc_object, SphinxDocString
import inspect
def mangle_docstrings(app, what, name, obj, options, lines,
reference_offset=[0]):
if what == 'module':
# Strip top title
title_re = re.compile(r'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*',
re.I|re.S)
lines[:] = title_re.sub('', "\n".join(lines)).split("\n")
else:
doc = get_doc_object(obj, what, "\n".join(lines))
lines[:] = str(doc).split("\n")
if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
obj.__name__:
if hasattr(obj, '__module__'):
v = dict(full_name="%s.%s" % (obj.__module__, obj.__name__))
else:
v = dict(full_name=obj.__name__)
lines += ['', '.. htmlonly::', '']
lines += [' %s' % x for x in
(app.config.numpydoc_edit_link % v).split("\n")]
# replace reference numbers so that there are no duplicates
references = []
for line in lines:
line = line.strip()
m = re.match(r'^.. \[([a-z0-9_.-])\]', line, re.I)
if m:
references.append(m.group(1))
# start renaming from the longest string, to avoid overwriting parts
references.sort(key=lambda x: -len(x))
if references:
for i, line in enumerate(lines):
for r in references:
if re.match(r'^\d+$', r):
new_r = "R%d" % (reference_offset[0] + int(r))
else:
new_r = "%s%d" % (r, reference_offset[0])
lines[i] = lines[i].replace('[%s]_' % r,
'[%s]_' % new_r)
lines[i] = lines[i].replace('.. [%s]' % r,
'.. [%s]' % new_r)
reference_offset[0] += len(references)
def mangle_signature(app, what, name, obj, options, sig, retann):
# Do not try to inspect classes that don't define `__init__`
if (inspect.isclass(obj) and
'initializes x; see ' in pydoc.getdoc(obj.__init__)):
return '', ''
if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
if not hasattr(obj, '__doc__'): return
doc = SphinxDocString(pydoc.getdoc(obj))
if doc['Signature']:
sig = re.sub("^[^(]*", "", doc['Signature'])
return sig, ''
def initialize(app):
try:
app.connect('autodoc-process-signature', mangle_signature)
except:
monkeypatch_sphinx_ext_autodoc()
def setup(app, get_doc_object_=get_doc_object):
global get_doc_object
get_doc_object = get_doc_object_
app.connect('autodoc-process-docstring', mangle_docstrings)
app.connect('builder-inited', initialize)
app.add_config_value('numpydoc_edit_link', None, True)
#------------------------------------------------------------------------------
# Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5)
#------------------------------------------------------------------------------
def monkeypatch_sphinx_ext_autodoc():
global _original_format_signature
import sphinx.ext.autodoc
if sphinx.ext.autodoc.format_signature is our_format_signature:
return
print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..."
_original_format_signature = sphinx.ext.autodoc.format_signature
sphinx.ext.autodoc.format_signature = our_format_signature
def our_format_signature(what, obj):
r = mangle_signature(None, what, None, obj, None, None, None)
if r is not None:
return r[0]
else:
return _original_format_signature(what, obj)
-96
View File
@@ -1,96 +0,0 @@
#
# A pair of directives for inserting content that will only appear in
# either html or latex.
#
from docutils.nodes import Body, Element
from docutils.writers.html4css1 import HTMLTranslator
try:
from sphinx.latexwriter import LaTeXTranslator
except ImportError:
from sphinx.writers.latex import LaTeXTranslator
import warnings
warnings.warn("The numpydoc.only_directives module is deprecated;"
"please use the only:: directive available in Sphinx >= 0.6",
DeprecationWarning, stacklevel=2)
from docutils.parsers.rst import directives
class html_only(Body, Element):
pass
class latex_only(Body, Element):
pass
def run(content, node_class, state, content_offset):
text = '\n'.join(content)
node = node_class(text)
state.nested_parse(content, content_offset, node)
return [node]
try:
from docutils.parsers.rst import Directive
except ImportError:
from docutils.parsers.rst.directives import _directives
def html_only_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
return run(content, html_only, state, content_offset)
def latex_only_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
return run(content, latex_only, state, content_offset)
for func in (html_only_directive, latex_only_directive):
func.content = 1
func.options = {}
func.arguments = None
_directives['htmlonly'] = html_only_directive
_directives['latexonly'] = latex_only_directive
else:
class OnlyDirective(Directive):
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
def run(self):
self.assert_has_content()
return run(self.content, self.node_class,
self.state, self.content_offset)
class HtmlOnlyDirective(OnlyDirective):
node_class = html_only
class LatexOnlyDirective(OnlyDirective):
node_class = latex_only
directives.register_directive('htmlonly', HtmlOnlyDirective)
directives.register_directive('latexonly', LatexOnlyDirective)
def setup(app):
app.add_node(html_only)
app.add_node(latex_only)
# Add visit/depart methods to HTML-Translator:
def visit_perform(self, node):
pass
def depart_perform(self, node):
pass
def visit_ignore(self, node):
node.children = []
def depart_ignore(self, node):
node.children = []
HTMLTranslator.visit_html_only = visit_perform
HTMLTranslator.depart_html_only = depart_perform
HTMLTranslator.visit_latex_only = visit_ignore
HTMLTranslator.depart_latex_only = depart_ignore
LaTeXTranslator.visit_html_only = visit_ignore
LaTeXTranslator.depart_html_only = depart_ignore
LaTeXTranslator.visit_latex_only = visit_perform
LaTeXTranslator.depart_latex_only = depart_perform
-162
View File
@@ -1,162 +0,0 @@
"""
==============
phantom_import
==============
Sphinx extension to make directives from ``sphinx.ext.autodoc`` and similar
extensions to use docstrings loaded from an XML file.
This extension loads an XML file in the Pydocweb format [1] and
creates a dummy module that contains the specified docstrings. This
can be used to get the current docstrings from a Pydocweb instance
without needing to rebuild the documented module.
.. [1] http://code.google.com/p/pydocweb
"""
import imp, sys, compiler, types, os, inspect, re
def setup(app):
app.connect('builder-inited', initialize)
app.add_config_value('phantom_import_file', None, True)
def initialize(app):
fn = app.config.phantom_import_file
if (fn and os.path.isfile(fn)):
print "[numpydoc] Phantom importing modules from", fn, "..."
import_phantom_module(fn)
#------------------------------------------------------------------------------
# Creating 'phantom' modules from an XML description
#------------------------------------------------------------------------------
def import_phantom_module(xml_file):
"""
Insert a fake Python module to sys.modules, based on a XML file.
The XML file is expected to conform to Pydocweb DTD. The fake
module will contain dummy objects, which guarantee the following:
- Docstrings are correct.
- Class inheritance relationships are correct (if present in XML).
- Function argspec is *NOT* correct (even if present in XML).
Instead, the function signature is prepended to the function docstring.
- Class attributes are *NOT* correct; instead, they are dummy objects.
Parameters
----------
xml_file : str
Name of an XML file to read
"""
import lxml.etree as etree
object_cache = {}
tree = etree.parse(xml_file)
root = tree.getroot()
# Sort items so that
# - Base classes come before classes inherited from them
# - Modules come before their contents
all_nodes = dict([(n.attrib['id'], n) for n in root])
def _get_bases(node, recurse=False):
bases = [x.attrib['ref'] for x in node.findall('base')]
if recurse:
j = 0
while True:
try:
b = bases[j]
except IndexError: break
if b in all_nodes:
bases.extend(_get_bases(all_nodes[b]))
j += 1
return bases
type_index = ['module', 'class', 'callable', 'object']
def base_cmp(a, b):
x = cmp(type_index.index(a.tag), type_index.index(b.tag))
if x != 0: return x
if a.tag == 'class' and b.tag == 'class':
a_bases = _get_bases(a, recurse=True)
b_bases = _get_bases(b, recurse=True)
x = cmp(len(a_bases), len(b_bases))
if x != 0: return x
if a.attrib['id'] in b_bases: return -1
if b.attrib['id'] in a_bases: return 1
return cmp(a.attrib['id'].count('.'), b.attrib['id'].count('.'))
nodes = root.getchildren()
nodes.sort(base_cmp)
# Create phantom items
for node in nodes:
name = node.attrib['id']
doc = (node.text or '').decode('string-escape') + "\n"
if doc == "\n": doc = ""
# create parent, if missing
parent = name
while True:
parent = '.'.join(parent.split('.')[:-1])
if not parent: break
if parent in object_cache: break
obj = imp.new_module(parent)
object_cache[parent] = obj
sys.modules[parent] = obj
# create object
if node.tag == 'module':
obj = imp.new_module(name)
obj.__doc__ = doc
sys.modules[name] = obj
elif node.tag == 'class':
bases = [object_cache[b] for b in _get_bases(node)
if b in object_cache]
bases.append(object)
init = lambda self: None
init.__doc__ = doc
obj = type(name, tuple(bases), {'__doc__': doc, '__init__': init})
obj.__name__ = name.split('.')[-1]
elif node.tag == 'callable':
funcname = node.attrib['id'].split('.')[-1]
argspec = node.attrib.get('argspec')
if argspec:
argspec = re.sub('^[^(]*', '', argspec)
doc = "%s%s\n\n%s" % (funcname, argspec, doc)
obj = lambda: 0
obj.__argspec_is_invalid_ = True
obj.func_name = funcname
obj.__name__ = name
obj.__doc__ = doc
if inspect.isclass(object_cache[parent]):
obj.__objclass__ = object_cache[parent]
else:
class Dummy(object): pass
obj = Dummy()
obj.__name__ = name
obj.__doc__ = doc
if inspect.isclass(object_cache[parent]):
obj.__get__ = lambda: None
object_cache[name] = obj
if parent:
if inspect.ismodule(object_cache[parent]):
obj.__module__ = parent
setattr(object_cache[parent], name.split('.')[-1], obj)
# Populate items
for node in root:
obj = object_cache.get(node.attrib['id'])
if obj is None: continue
for ref in node.findall('ref'):
if node.tag == 'class':
if ref.attrib['ref'].startswith(node.attrib['id'] + '.'):
setattr(obj, ref.attrib['name'],
object_cache.get(ref.attrib['ref']))
else:
setattr(obj, ref.attrib['name'],
object_cache.get(ref.attrib['ref']))
-477
View File
@@ -1,477 +0,0 @@
"""
A special directive for generating a matplotlib plot.
.. warning::
This is a hacked version of plot_directive.py from Matplotlib.
It's very much subject to change!
Usage
-----
Can be used like this::
.. plot:: examples/example.py
.. plot::
import matplotlib.pyplot as plt
plt.plot([1,2,3], [4,5,6])
.. plot::
A plotting example:
>>> import matplotlib.pyplot as plt
>>> plt.plot([1,2,3], [4,5,6])
The content is interpreted as doctest formatted if it has a line starting
with ``>>>``.
The ``plot`` directive supports the options
format : {'python', 'doctest'}
Specify the format of the input
include-source : bool
Whether to display the source code. Default can be changed in conf.py
and the ``image`` directive options ``alt``, ``height``, ``width``,
``scale``, ``align``, ``class``.
Configuration options
---------------------
The plot directive has the following configuration options:
plot_output_dir
Directory (relative to config file) where to store plot output.
Should be inside the static directory. (Default: 'static')
plot_pre_code
Code that should be executed before each plot.
plot_rcparams
Dictionary of Matplotlib rc-parameter overrides.
Has 'sane' defaults.
plot_include_source
Default value for the include-source option
plot_formats
The set of files to generate. Default: ['png', 'pdf', 'hires.png'],
ie. everything.
TODO
----
* Don't put temp files to _static directory, but do function in the way
the pngmath directive works, and plot figures only during output writing.
* Refactor Latex output; now it's plain images, but it would be nice
to make them appear side-by-side, or in floats.
"""
import sys, os, glob, shutil, imp, warnings, cStringIO, re, textwrap
import warnings
warnings.warn("A plot_directive module is also available under "
"matplotlib.sphinxext; expect this numpydoc.plot_directive "
"module to be deprecated after relevant features have been "
"integrated there.",
FutureWarning, stacklevel=2)
def setup(app):
setup.app = app
setup.config = app.config
setup.confdir = app.confdir
static_path = '_static'
if hasattr(app.config, 'html_static_path') and app.config.html_static_path:
static_path = app.config.html_static_path[0]
app.add_config_value('plot_output_dir', static_path, True)
app.add_config_value('plot_pre_code', '', True)
app.add_config_value('plot_rcparams', sane_rcparameters, True)
app.add_config_value('plot_include_source', False, True)
app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)
app.add_directive('plot', plot_directive, True, (0, 1, False),
**plot_directive_options)
sane_rcparameters = {
'font.size': 9,
'axes.titlesize': 9,
'axes.labelsize': 9,
'xtick.labelsize': 9,
'ytick.labelsize': 9,
'legend.fontsize': 9,
'figure.figsize': (4, 3),
}
#------------------------------------------------------------------------------
# Run code and capture figures
#------------------------------------------------------------------------------
import matplotlib
import matplotlib.cbook as cbook
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.image as image
from matplotlib import _pylab_helpers
def contains_doctest(text):
r = re.compile(r'^\s*>>>', re.M)
m = r.match(text)
return bool(m)
def unescape_doctest(text):
"""
Extract code from a piece of text, which contains either Python code
or doctests.
"""
if not contains_doctest(text):
return text
code = ""
for line in text.split("\n"):
m = re.match(r'^\s*(>>>|...) (.*)$', line)
if m:
code += m.group(2) + "\n"
elif line.strip():
code += "# " + line.strip() + "\n"
else:
code += "\n"
return code
def run_code(code, code_path):
# Change the working directory to the directory of the example, so
# it can get at its data files, if any.
pwd = os.getcwd()
old_sys_path = list(sys.path)
if code_path is not None:
dirname = os.path.abspath(os.path.dirname(code_path))
os.chdir(dirname)
sys.path.insert(0, dirname)
# Redirect stdout
stdout = sys.stdout
sys.stdout = cStringIO.StringIO()
try:
code = unescape_doctest(code)
ns = {}
exec setup.config.plot_pre_code in ns
exec code in ns
finally:
os.chdir(pwd)
sys.path[:] = old_sys_path
sys.stdout = stdout
return ns
#------------------------------------------------------------------------------
# Generating figures
#------------------------------------------------------------------------------
def out_of_date(original, derived):
"""
Returns True if derivative is out-of-date wrt original,
both of which are full file paths.
"""
return (not os.path.exists(derived)
or os.stat(derived).st_mtime < os.stat(original).st_mtime)
def makefig(code, code_path, output_dir, output_base, config):
"""
run a pyplot script and save the low and high res PNGs and a PDF in _static
"""
included_formats = config.plot_formats
if type(included_formats) is str:
included_formats = eval(included_formats)
formats = [x for x in [('png', 80), ('hires.png', 200), ('pdf', 50)]
if x[0] in config.plot_formats]
all_exists = True
# Look for single-figure output files first
for format, dpi in formats:
output_path = os.path.join(output_dir, '%s.%s' % (output_base, format))
if out_of_date(code_path, output_path):
all_exists = False
break
if all_exists:
return [output_base]
# Then look for multi-figure output files
image_names = []
for i in xrange(1000):
image_names.append('%s_%02d' % (output_base, i))
for format, dpi in formats:
output_path = os.path.join(output_dir,
'%s.%s' % (image_names[-1], format))
if out_of_date(code_path, output_path):
all_exists = False
break
if not all_exists:
# assume that if we have one, we have them all
all_exists = (i > 0)
break
if all_exists:
return image_names
# We didn't find the files, so build them
print "-- Plotting figures %s" % output_base
# Clear between runs
plt.close('all')
# Reset figure parameters
matplotlib.rcdefaults()
matplotlib.rcParams.update(config.plot_rcparams)
# Run code
run_code(code, code_path)
# Collect images
image_names = []
fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
for i, figman in enumerate(fig_managers):
if len(fig_managers) == 1:
name = output_base
else:
name = "%s_%02d" % (output_base, i)
image_names.append(name)
for format, dpi in formats:
path = os.path.join(output_dir, '%s.%s' % (name, format))
figman.canvas.figure.savefig(path, dpi=dpi)
return image_names
#------------------------------------------------------------------------------
# Generating output
#------------------------------------------------------------------------------
from docutils import nodes, utils
import jinja
TEMPLATE = """
{{source_code}}
.. htmlonly::
{% if source_code %}
(`Source code <{{source_link}}>`__)
{% endif %}
.. admonition:: Output
:class: plot-output
{% for name in image_names %}
.. figure:: {{link_dir}}/{{name}}.png
{%- for option in options %}
{{option}}
{% endfor %}
(
{%- if not source_code %}`Source code <{{source_link}}>`__, {% endif -%}
`PNG <{{link_dir}}/{{name}}.hires.png>`__,
`PDF <{{link_dir}}/{{name}}.pdf>`__)
{% endfor %}
.. latexonly::
{% for name in image_names %}
.. image:: {{link_dir}}/{{name}}.pdf
{% endfor %}
"""
def run(arguments, content, options, state_machine, state, lineno):
if arguments and content:
raise RuntimeError("plot:: directive can't have both args and content")
document = state_machine.document
config = document.settings.env.config
options.setdefault('include-source', config.plot_include_source)
if options['include-source'] is None:
options['include-source'] = config.plot_include_source
# determine input
rst_file = document.attributes['source']
rst_dir = os.path.dirname(rst_file)
if arguments:
file_name = os.path.join(rst_dir, directives.uri(arguments[0]))
code = open(file_name, 'r').read()
output_base = os.path.basename(file_name)
else:
file_name = rst_file
code = textwrap.dedent("\n".join(map(str, content)))
counter = document.attributes.get('_plot_counter', 0) + 1
document.attributes['_plot_counter'] = counter
output_base = '%d-%s' % (counter, os.path.basename(file_name))
rel_name = relpath(file_name, setup.confdir)
base, ext = os.path.splitext(output_base)
if ext in ('.py', '.rst', '.txt'):
output_base = base
# is it in doctest format?
is_doctest = contains_doctest(code)
if options.has_key('format'):
if options['format'] == 'python':
is_doctest = False
else:
is_doctest = True
# determine output
file_rel_dir = os.path.dirname(rel_name)
while file_rel_dir.startswith(os.path.sep):
file_rel_dir = file_rel_dir[1:]
output_dir = os.path.join(setup.confdir, setup.config.plot_output_dir,
file_rel_dir)
if not os.path.exists(output_dir):
cbook.mkdirs(output_dir)
# copy script
target_name = os.path.join(output_dir, output_base)
f = open(target_name, 'w')
f.write(unescape_doctest(code))
f.close()
source_link = relpath(target_name, rst_dir)
# determine relative reference
link_dir = relpath(output_dir, rst_dir)
# make figures
try:
image_names = makefig(code, file_name, output_dir, output_base, config)
except RuntimeError, err:
reporter = state.memo.reporter
sm = reporter.system_message(3, "Exception occurred rendering plot",
line=lineno)
return [sm]
# generate output
if options['include-source']:
if is_doctest:
lines = ['']
else:
lines = ['.. code-block:: python', '']
lines += [' %s' % row.rstrip() for row in code.split('\n')]
source_code = "\n".join(lines)
else:
source_code = ""
opts = [':%s: %s' % (key, val) for key, val in options.items()
if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
result = jinja.from_string(TEMPLATE).render(
link_dir=link_dir.replace(os.path.sep, '/'),
source_link=source_link,
options=opts,
image_names=image_names,
source_code=source_code)
lines = result.split("\n")
if len(lines):
state_machine.insert_input(
lines, state_machine.input_lines.source(0))
return []
if hasattr(os.path, 'relpath'):
relpath = os.path.relpath
else:
def relpath(target, base=os.curdir):
"""
Return a relative path to the target from either the current
dir or an optional base dir. Base can be a directory
specified either as absolute or relative to current dir.
"""
if not os.path.exists(target):
raise OSError, 'Target does not exist: '+target
if not os.path.isdir(base):
raise OSError, 'Base is not a directory or does not exist: '+base
base_list = (os.path.abspath(base)).split(os.sep)
target_list = (os.path.abspath(target)).split(os.sep)
# On the windows platform the target may be on a completely
# different drive from the base.
if os.name in ['nt','dos','os2'] and base_list[0] <> target_list[0]:
raise OSError, 'Target is on a different drive to base. Target: '+target_list[0].upper()+', base: '+base_list[0].upper()
# Starting from the filepath root, work out how much of the
# filepath is shared by base and target.
for i in range(min(len(base_list), len(target_list))):
if base_list[i] <> target_list[i]: break
else:
# If we broke out of the loop, i is pointing to the first
# differing path elements. If we didn't break out of the
# loop, i is pointing to identical path elements.
# Increment i so that in all cases it points to the first
# differing path elements.
i+=1
rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:]
return os.path.join(*rel_list)
#------------------------------------------------------------------------------
# plot:: directive registration etc.
#------------------------------------------------------------------------------
from docutils.parsers.rst import directives
try:
# docutils 0.4
from docutils.parsers.rst.directives.images import align
except ImportError:
# docutils 0.5
from docutils.parsers.rst.directives.images import Image
align = Image.align
def plot_directive(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
return run(arguments, content, options, state_machine, state, lineno)
plot_directive.__doc__ = __doc__
def _option_boolean(arg):
if not arg or not arg.strip():
return None
elif arg.strip().lower() in ('no', '0', 'false'):
return False
elif arg.strip().lower() in ('yes', '1', 'true'):
return True
else:
raise ValueError('"%s" unknown boolean' % arg)
def _option_format(arg):
return directives.choice(arg, ('python', 'lisp'))
plot_directive_options = {'alt': directives.unchanged,
'height': directives.length_or_unitless,
'width': directives.length_or_percentage_or_unitless,
'scale': directives.nonnegative_int,
'align': align,
'class': directives.class_option,
'include-source': _option_boolean,
'format': _option_format,
}
-31
View File
@@ -1,31 +0,0 @@
from distutils.core import setup
import setuptools
import sys, os
version = "0.2.dev"
setup(
name="numpydoc",
packages=["numpydoc"],
package_dir={"numpydoc": ""},
version=version,
description="Sphinx extension to support docstrings in Numpy format",
# classifiers from http://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=["Development Status :: 3 - Alpha",
"Environment :: Plugins",
"License :: OSI Approved :: BSD License",
"Topic :: Documentation"],
keywords="sphinx numpy",
author="Pauli Virtanen and others",
author_email="pav@iki.fi",
url="http://projects.scipy.org/numpy/browser/trunk/doc/sphinxext",
license="BSD",
zip_safe=False,
install_requires=["Sphinx >= 0.5"],
package_data={'numpydoc': 'tests'},
entry_points={
"console_scripts": [
"autosummary_generate = numpydoc.autosummary_generate:main",
],
},
)
@@ -1,490 +0,0 @@
# -*- encoding:utf-8 -*-
import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from docscrape import NumpyDocString, FunctionDoc
from docscrape_sphinx import SphinxDocString
from nose.tools import *
doc_txt = '''\
numpy.multivariate_normal(mean, cov, shape=None)
Draw values from a multivariate normal distribution with specified
mean and covariance.
The multivariate normal or Gaussian distribution is a generalisation
of the one-dimensional normal distribution to higher dimensions.
Parameters
----------
mean : (N,) ndarray
Mean of the N-dimensional distribution.
.. math::
(1+2+3)/3
cov : (N,N) ndarray
Covariance matrix of the distribution.
shape : tuple of ints
Given a shape of, for example, (m,n,k), m*n*k samples are
generated, and packed in an m-by-n-by-k arrangement. Because
each sample is N-dimensional, the output shape is (m,n,k,N).
Returns
-------
out : ndarray
The drawn samples, arranged according to `shape`. If the
shape given is (m,n,...), then the shape of `out` is is
(m,n,...,N).
In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
value drawn from the distribution.
Warnings
--------
Certain warnings apply.
Notes
-----
Instead of specifying the full covariance matrix, popular
approximations include:
- Spherical covariance (`cov` is a multiple of the identity matrix)
- Diagonal covariance (`cov` has non-negative elements only on the diagonal)
This geometrical property can be seen in two dimensions by plotting
generated data-points:
>>> mean = [0,0]
>>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
>>> x,y = multivariate_normal(mean,cov,5000).T
>>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
Note that the covariance matrix must be symmetric and non-negative
definite.
References
----------
.. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
Processes," 3rd ed., McGraw-Hill Companies, 1991
.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
2nd ed., Wiley, 2001.
See Also
--------
some, other, funcs
otherfunc : relationship
Examples
--------
>>> mean = (1,2)
>>> cov = [[1,0],[1,0]]
>>> x = multivariate_normal(mean,cov,(3,3))
>>> print x.shape
(3, 3, 2)
The following is probably true, given that 0.6 is roughly twice the
standard deviation:
>>> print list( (x[0,0,:] - mean) < 0.6 )
[True, True]
.. index:: random
:refguide: random;distributions, random;gauss
'''
doc = NumpyDocString(doc_txt)
def test_signature():
assert doc['Signature'].startswith('numpy.multivariate_normal(')
assert doc['Signature'].endswith('shape=None)')
def test_summary():
assert doc['Summary'][0].startswith('Draw values')
assert doc['Summary'][-1].endswith('covariance.')
def test_extended_summary():
assert doc['Extended Summary'][0].startswith('The multivariate normal')
def test_parameters():
assert_equal(len(doc['Parameters']), 3)
assert_equal([n for n,_,_ in doc['Parameters']], ['mean','cov','shape'])
arg, arg_type, desc = doc['Parameters'][1]
assert_equal(arg_type, '(N,N) ndarray')
assert desc[0].startswith('Covariance matrix')
assert doc['Parameters'][0][-1][-2] == ' (1+2+3)/3'
def test_returns():
assert_equal(len(doc['Returns']), 1)
arg, arg_type, desc = doc['Returns'][0]
assert_equal(arg, 'out')
assert_equal(arg_type, 'ndarray')
assert desc[0].startswith('The drawn samples')
assert desc[-1].endswith('distribution.')
def test_notes():
assert doc['Notes'][0].startswith('Instead')
assert doc['Notes'][-1].endswith('definite.')
assert_equal(len(doc['Notes']), 17)
def test_references():
assert doc['References'][0].startswith('..')
assert doc['References'][-1].endswith('2001.')
def test_examples():
assert doc['Examples'][0].startswith('>>>')
assert doc['Examples'][-1].endswith('True]')
def test_index():
assert_equal(doc['index']['default'], 'random')
print doc['index']
assert_equal(len(doc['index']), 2)
assert_equal(len(doc['index']['refguide']), 2)
def non_blank_line_by_line_compare(a,b):
a = [l for l in a.split('\n') if l.strip()]
b = [l for l in b.split('\n') if l.strip()]
for n,line in enumerate(a):
if not line == b[n]:
raise AssertionError("Lines %s of a and b differ: "
"\n>>> %s\n<<< %s\n" %
(n,line,b[n]))
def test_str():
non_blank_line_by_line_compare(str(doc),
"""numpy.multivariate_normal(mean, cov, shape=None)
Draw values from a multivariate normal distribution with specified
mean and covariance.
The multivariate normal or Gaussian distribution is a generalisation
of the one-dimensional normal distribution to higher dimensions.
Parameters
----------
mean : (N,) ndarray
Mean of the N-dimensional distribution.
.. math::
(1+2+3)/3
cov : (N,N) ndarray
Covariance matrix of the distribution.
shape : tuple of ints
Given a shape of, for example, (m,n,k), m*n*k samples are
generated, and packed in an m-by-n-by-k arrangement. Because
each sample is N-dimensional, the output shape is (m,n,k,N).
Returns
-------
out : ndarray
The drawn samples, arranged according to `shape`. If the
shape given is (m,n,...), then the shape of `out` is is
(m,n,...,N).
In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
value drawn from the distribution.
Warnings
--------
Certain warnings apply.
See Also
--------
`some`_, `other`_, `funcs`_
`otherfunc`_
relationship
Notes
-----
Instead of specifying the full covariance matrix, popular
approximations include:
- Spherical covariance (`cov` is a multiple of the identity matrix)
- Diagonal covariance (`cov` has non-negative elements only on the diagonal)
This geometrical property can be seen in two dimensions by plotting
generated data-points:
>>> mean = [0,0]
>>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
>>> x,y = multivariate_normal(mean,cov,5000).T
>>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
Note that the covariance matrix must be symmetric and non-negative
definite.
References
----------
.. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
Processes," 3rd ed., McGraw-Hill Companies, 1991
.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
2nd ed., Wiley, 2001.
Examples
--------
>>> mean = (1,2)
>>> cov = [[1,0],[1,0]]
>>> x = multivariate_normal(mean,cov,(3,3))
>>> print x.shape
(3, 3, 2)
The following is probably true, given that 0.6 is roughly twice the
standard deviation:
>>> print list( (x[0,0,:] - mean) < 0.6 )
[True, True]
.. index:: random
:refguide: random;distributions, random;gauss""")
def test_sphinx_str():
sphinx_doc = SphinxDocString(doc_txt)
non_blank_line_by_line_compare(str(sphinx_doc),
"""
.. index:: random
single: random;distributions, random;gauss
Draw values from a multivariate normal distribution with specified
mean and covariance.
The multivariate normal or Gaussian distribution is a generalisation
of the one-dimensional normal distribution to higher dimensions.
:Parameters:
**mean** : (N,) ndarray
Mean of the N-dimensional distribution.
.. math::
(1+2+3)/3
**cov** : (N,N) ndarray
Covariance matrix of the distribution.
**shape** : tuple of ints
Given a shape of, for example, (m,n,k), m*n*k samples are
generated, and packed in an m-by-n-by-k arrangement. Because
each sample is N-dimensional, the output shape is (m,n,k,N).
:Returns:
**out** : ndarray
The drawn samples, arranged according to `shape`. If the
shape given is (m,n,...), then the shape of `out` is is
(m,n,...,N).
In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
value drawn from the distribution.
.. warning::
Certain warnings apply.
.. seealso::
:obj:`some`, :obj:`other`, :obj:`funcs`
:obj:`otherfunc`
relationship
.. rubric:: Notes
Instead of specifying the full covariance matrix, popular
approximations include:
- Spherical covariance (`cov` is a multiple of the identity matrix)
- Diagonal covariance (`cov` has non-negative elements only on the diagonal)
This geometrical property can be seen in two dimensions by plotting
generated data-points:
>>> mean = [0,0]
>>> cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
>>> x,y = multivariate_normal(mean,cov,5000).T
>>> plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
Note that the covariance matrix must be symmetric and non-negative
definite.
.. rubric:: References
.. [1] A. Papoulis, "Probability, Random Variables, and Stochastic
Processes," 3rd ed., McGraw-Hill Companies, 1991
.. [2] R.O. Duda, P.E. Hart, and D.G. Stork, "Pattern Classification,"
2nd ed., Wiley, 2001.
.. rubric:: Examples
>>> mean = (1,2)
>>> cov = [[1,0],[1,0]]
>>> x = multivariate_normal(mean,cov,(3,3))
>>> print x.shape
(3, 3, 2)
The following is probably true, given that 0.6 is roughly twice the
standard deviation:
>>> print list( (x[0,0,:] - mean) < 0.6 )
[True, True]
""")
doc2 = NumpyDocString("""
Returns array of indices of the maximum values of along the given axis.
Parameters
----------
a : {array_like}
Array to look in.
axis : {None, integer}
If None, the index is into the flattened array, otherwise along
the specified axis""")
def test_parameters_without_extended_description():
assert_equal(len(doc2['Parameters']), 2)
doc3 = NumpyDocString("""
my_signature(*params, **kwds)
Return this and that.
""")
def test_escape_stars():
signature = str(doc3).split('\n')[0]
assert_equal(signature, 'my_signature(\*params, \*\*kwds)')
doc4 = NumpyDocString(
"""a.conj()
Return an array with all complex-valued elements conjugated.""")
def test_empty_extended_summary():
assert_equal(doc4['Extended Summary'], [])
doc5 = NumpyDocString(
"""
a.something()
Raises
------
LinAlgException
If array is singular.
""")
def test_raises():
assert_equal(len(doc5['Raises']), 1)
name,_,desc = doc5['Raises'][0]
assert_equal(name,'LinAlgException')
assert_equal(desc,['If array is singular.'])
def test_see_also():
doc6 = NumpyDocString(
"""
z(x,theta)
See Also
--------
func_a, func_b, func_c
func_d : some equivalent func
foo.func_e : some other func over
multiple lines
func_f, func_g, :meth:`func_h`, func_j,
func_k
:obj:`baz.obj_q`
:class:`class_j`: fubar
foobar
""")
assert len(doc6['See Also']) == 12
for func, desc, role in doc6['See Also']:
if func in ('func_a', 'func_b', 'func_c', 'func_f',
'func_g', 'func_h', 'func_j', 'func_k', 'baz.obj_q'):
assert(not desc)
else:
assert(desc)
if func == 'func_h':
assert role == 'meth'
elif func == 'baz.obj_q':
assert role == 'obj'
elif func == 'class_j':
assert role == 'class'
else:
assert role is None
if func == 'func_d':
assert desc == ['some equivalent func']
elif func == 'foo.func_e':
assert desc == ['some other func over', 'multiple lines']
elif func == 'class_j':
assert desc == ['fubar', 'foobar']
def test_see_also_print():
class Dummy(object):
"""
See Also
--------
func_a, func_b
func_c : some relationship
goes here
func_d
"""
pass
obj = Dummy()
s = str(FunctionDoc(obj, role='func'))
assert(':func:`func_a`, :func:`func_b`' in s)
assert(' some relationship' in s)
assert(':func:`func_d`' in s)
doc7 = NumpyDocString("""
Doc starts on second line.
""")
def test_empty_first_line():
assert doc7['Summary'][0].startswith('Doc starts')
def test_no_summary():
str(SphinxDocString("""
Parameters
----------"""))
def test_unicode():
doc = SphinxDocString("""
öäöäöäöäöåååå
öäöäöäööäååå
Parameters
----------
ååå : äää
ööö
Returns
-------
ååå : ööö
äää
""")
assert doc['Summary'][0] == u'öäöäöäöäöåååå'.encode('utf-8')
+2
View File
@@ -0,0 +1,2 @@
Here are various example files for configuration of routes and gae.
To use them, move them to main web2py folder and customize them.
+1 -1
View File
@@ -77,7 +77,7 @@ name: web2py Web Framework
# The CSS stylesheet for HTML output. Can be the name of a built-in
# stylesheet, or the name of a file.
css: epydoc.css
css: extras/epydoc/epydoc.css
# The documented project's URL.
url: http://www.web2py.com

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

+2 -2
View File
@@ -151,7 +151,7 @@ def presentation(root):
canvas.pack()
root.update()
logo = 'splashlogo.gif'
logo = 'extras/icons/splashlogo.gif'
if os.path.exists(logo):
img = Tkinter.PhotoImage(file=logo)
pnl = Tkinter.Label(canvas, image=img, background='white', bd=0)
@@ -199,7 +199,7 @@ class web2pyDialog(object):
self.menu = Tkinter.Menu(self.root)
servermenu = Tkinter.Menu(self.menu, tearoff=0)
httplog = os.path.join(self.options.folder, 'httpserver.log')
iconphoto = 'web2py.gif'
iconphoto = 'extras/icons/web2py.gif'
if os.path.exists(iconphoto):
img = Tkinter.PhotoImage(file=iconphoto)
self.root.tk.call('wm', 'iconphoto', self.root._w, img)
-27
View File
@@ -1,27 +0,0 @@
#!/usr/bin/env python
import gluon
from gluon.fileutils import untar
import os
import sys
def main():
path = gluon.__path__
out_path = os.getcwd()
try:
if sys.argv[1] and os.path.exists(sys.argv[1]):# To untar the web2py env to the selected path
out_path = sys.argv[1]
else:
os.mkdir(sys.argv[1])
out_path = sys.argv[1]
except:
pass
try:
print "Creating a web2py env in: " + out_path
untar(os.path.join(path[0],'env.tar'),out_path)
except:
print "Failed to create the web2py env"
print "Please reinstall web2py from pip"
if __name__ == '__main__':
main()
-24
View File
@@ -1,24 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
path = os.getcwd()
try:
if sys.argv[1] and os.path.exists(sys.argv[1]):
path = sys.argv[1]
except:
pass
os.chdir(path)
sys.path = [path]+[p for p in sys.path if not p==path]
# import gluon.import_all ##### This should be uncommented for py2exe.py
import gluon.widget
def main():
# Start Web2py and Web2py cron service!
gluon.widget.start(cron=True)
if __name__ == '__main__':
main()
View File
-27
View File
@@ -1,27 +0,0 @@
#!/usr/bin/env python
import gluon
from gluon.fileutils import untar
import os
import sys
def main():
path = gluon.__path__
out_path = os.getcwd()
try:
if sys.argv[1] and os.path.exists(sys.argv[1]):# To untar the web2py env to the selected path
out_path = sys.argv[1]
else:
os.mkdir(sys.argv[1])
out_path = sys.argv[1]
except:
pass
try:
print "Creating a web2py env in: " + out_path
untar(os.path.join(path[0],'env.tar'),out_path)
except:
print "Failed to create the web2py env"
print "Please reinstall web2py from pip"
if __name__ == '__main__':
main()
-55
View File
@@ -1,55 +0,0 @@
#!/usr/bin/env python
import os
import sys
"""
Author: Christopher Steel on behalf of Voice of Access
Copyright: Copyrighted (c) by Massimo Di Pierro (2007-2013)
web2py_clone becomes part of the web2py distribution available
on Pypi via 'pip install web2py'
web2py_clone is one of multiple commands that become available after running
'pip install web2py' in a virtual environment. It requires
mercurial to be installed in the virtual environment.
web2py_clone creates a local clone from the Web2py google code
project in the directory "./web2py," a directory called web2py
one directory up from the location of this script.
./bin/web2py_clone
./web2py
"""
def main():
iwd = cwd = os.getcwd() # set initial and current working directories
script_filename = os.path.realpath(__file__)
script_dirname = os.path.dirname(script_filename)
try:
print ("cwd now: %s" % cwd)
except:
print ("command failed %s" % cwd)
try:
os.chdir(script_dirname)
cwd = os.getcwd()
print ("cwd now: %s" % cwd)
source = "https://code.google.com/p/web2py/"
target = os.path.join('..','web2py')
print ("attempting to clone %s" % source)
print ("to %s" % target)
if os.path.isdir(target):
print ("found directory called web2py at %s" % target)
print ("is web2py already installed?")
print ("aborting clone attempt")
else:
os.system("hg clone %s %s" % (source,target))
os.chdir(iwd) # return to our initial working directory
cwd = iwd # set current working directory
except:
print ("web2py-clone failed in second try statement %s" % cwd)
if __name__ == '__main__':
main()
-24
View File
@@ -1,24 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
path = os.getcwd()
try:
if sys.argv[1] and os.path.exists(sys.argv[1]):
path = sys.argv[1]
except:
pass
os.chdir(path)
sys.path = [path]+[p for p in sys.path if not p==path]
# import gluon.import_all ##### This should be uncommented for py2exe.py
import gluon.widget
def main():
# Start Web2py and Web2py cron service!
gluon.widget.start(cron=True)
if __name__ == '__main__':
main()