diff options
Diffstat (limited to 'doc')
47 files changed, 409 insertions, 159 deletions
diff --git a/doc/HOWTO_RELEASE.rst.txt b/doc/HOWTO_RELEASE.rst.txt index b933cbecd..d6746f4d6 100644 --- a/doc/HOWTO_RELEASE.rst.txt +++ b/doc/HOWTO_RELEASE.rst.txt @@ -284,11 +284,14 @@ Now, set ``release=True`` in setup.py, then git tag <version> git push origin <version> -Update the version of the trunk -------------------------------- +Update the version of the master branch +--------------------------------------- Increment the release number in setup.py. Release candidates should have "rc1" (or "rc2", "rcN") appended to the X.Y.Z format. +Also create a new version hash in cversions.txt and a corresponding version +define NPY_x_y_API_VERSION in numpyconfig.h + Make the release ---------------- The tar-files and binary releases for distribution should be uploaded to SourceForge, diff --git a/doc/Makefile b/doc/Makefile index 03b327079..52dd1ef06 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -166,3 +166,16 @@ linkcheck: generate @echo @echo "Link check complete; look for any errors in the above output " \ "or in build/linkcheck/output.txt." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) build/texinfo + @echo + @echo "Build finished. The Texinfo files are in build/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) build/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C build/texinfo info + @echo "makeinfo finished; the Info files are in build/texinfo." diff --git a/doc/cdoc/numpyfilter.py b/doc/cdoc/numpyfilter.py index 5768c7850..4a93141dd 100755 --- a/doc/cdoc/numpyfilter.py +++ b/doc/cdoc/numpyfilter.py @@ -6,6 +6,8 @@ Interpret C comments as ReStructuredText, and replace them by the HTML output. Also, add Doxygen /** and /**< syntax automatically where appropriate. """ +from __future__ import division + import sys import re import os diff --git a/doc/cython/run_test.py b/doc/cython/run_test.py index 96388011e..64918ed9c 100755 --- a/doc/cython/run_test.py +++ b/doc/cython/run_test.py @@ -1,3 +1,5 @@ #!/usr/bin/env python +from __future__ import division + from numpyx import test test() diff --git a/doc/cython/setup.py b/doc/cython/setup.py index 270e11c56..0b063fef9 100755 --- a/doc/cython/setup.py +++ b/doc/cython/setup.py @@ -3,7 +3,9 @@ Note: Cython is the successor project to Pyrex. For more information, see http://cython.org. + """ +from __future__ import division from distutils.core import setup from distutils.extension import Extension diff --git a/doc/example.py b/doc/example.py index 5958c2db5..5c9d3d27e 100644 --- a/doc/example.py +++ b/doc/example.py @@ -8,6 +8,8 @@ extend over multiple lines, the closing three quotation marks must be on a line by itself, preferably preceeded by a blank line. """ +from __future__ import division + import os # standard library imports first # Do NOT import using *, e.g. from numpy import * diff --git a/doc/newdtype_example/example.py b/doc/newdtype_example/example.py index 7ee64ca00..b9ccc465b 100644 --- a/doc/newdtype_example/example.py +++ b/doc/newdtype_example/example.py @@ -1,3 +1,5 @@ +from __future__ import division + import floatint.floatint as ff import numpy as np diff --git a/doc/newdtype_example/floatint/__init__.py b/doc/newdtype_example/floatint/__init__.py index e69de29bb..5c6aac4d6 100644 --- a/doc/newdtype_example/floatint/__init__.py +++ b/doc/newdtype_example/floatint/__init__.py @@ -0,0 +1,3 @@ +from __future__ import division + + diff --git a/doc/newdtype_example/setup.py b/doc/newdtype_example/setup.py index 3b9d75578..2d9ed6c99 100644 --- a/doc/newdtype_example/setup.py +++ b/doc/newdtype_example/setup.py @@ -1,3 +1,4 @@ +from __future__ import division from numpy.distutils.core import setup diff --git a/doc/numpybook/comparison/ctypes/filter.py b/doc/numpybook/comparison/ctypes/filter.py index 1b322aca3..ebc274f31 100644 --- a/doc/numpybook/comparison/ctypes/filter.py +++ b/doc/numpybook/comparison/ctypes/filter.py @@ -1,3 +1,5 @@ +from __future__ import division + __all__ = ['filter2d'] import numpy as N diff --git a/doc/numpybook/comparison/ctypes/interface.py b/doc/numpybook/comparison/ctypes/interface.py index e237f8ded..ab1b14731 100644 --- a/doc/numpybook/comparison/ctypes/interface.py +++ b/doc/numpybook/comparison/ctypes/interface.py @@ -1,3 +1,5 @@ +from __future__ import division + __all__ = ['add', 'filter2d'] import numpy as N diff --git a/doc/numpybook/comparison/pyrex/setup.py b/doc/numpybook/comparison/pyrex/setup.py index 695639d9e..f0c764955 100644 --- a/doc/numpybook/comparison/pyrex/setup.py +++ b/doc/numpybook/comparison/pyrex/setup.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import division from distutils.core import setup from distutils.extension import Extension diff --git a/doc/numpybook/comparison/timing.py b/doc/numpybook/comparison/timing.py index 92f6a50d2..18004855e 100644 --- a/doc/numpybook/comparison/timing.py +++ b/doc/numpybook/comparison/timing.py @@ -1,3 +1,4 @@ +from __future__ import division import timeit diff --git a/doc/numpybook/comparison/weave/filter.py b/doc/numpybook/comparison/weave/filter.py index 6fc16c79f..519a54c5b 100644 --- a/doc/numpybook/comparison/weave/filter.py +++ b/doc/numpybook/comparison/weave/filter.py @@ -1,8 +1,10 @@ +from __future__ import division + from scipy import weave, zeros_like def filter(a): if a.ndim != 2: - raise ValueError, "a must be 2-d" + raise ValueError("a must be 2-d") code = r""" int i,j; for(i=1;i<Na[0]-1;i++) { diff --git a/doc/numpybook/comparison/weave/inline.py b/doc/numpybook/comparison/weave/inline.py index bfac588aa..1f98b7a62 100644 --- a/doc/numpybook/comparison/weave/inline.py +++ b/doc/numpybook/comparison/weave/inline.py @@ -1,9 +1,11 @@ +from __future__ import division + from scipy import weave from numpy import rand, zeros_like def example1(a): if not isinstance(a, list): - raise ValueError, "argument must be a list" + raise ValueError("argument must be a list") code = r""" int i; py::tuple results(2); @@ -18,7 +20,7 @@ def example1(a): def arr(a): if a.ndim != 2: - raise ValueError, "a must be 2-d" + raise ValueError("a must be 2-d") code = r""" int i,j; for(i=1;i<Na[0]-1;i++) { diff --git a/doc/numpybook/runcode.py b/doc/numpybook/runcode.py index 7e696c9b3..92784d34e 100644 --- a/doc/numpybook/runcode.py +++ b/doc/numpybook/runcode.py @@ -1,17 +1,20 @@ -# This script takes a lyx file and runs the python code in it. -# Then rewrites the lyx file again. -# -# Each section of code portion is assumed to be in the same namespace -# where a from numpy import * has been applied -# -# If a PYNEW inside a Note is encountered, the name space is restarted -# -# The output (if any) is replaced in the file -# by the output produced during the code run. -# -# Options: -# -n name of code section (default MyCode) -# +""" +This script takes a lyx file and runs the python code in it. + Then rewrites the lyx file again. + +Each section of code portion is assumed to be in the same namespace +where a from numpy import * has been applied + + If a PYNEW inside a Note is encountered, the name space is restarted + +The output (if any) is replaced in the file + by the output produced during the code run. + +Options: + -n name of code section (default MyCode) + +""" +from __future__ import division import sys import optparse @@ -33,7 +36,7 @@ def getoutput(tstr, dic): except SyntaxError: try: res = None - exec code in dic + exec(code, dic) finally: sys.stdout = sys.__stdout__ if res is None: @@ -94,8 +97,8 @@ def runpycode(lyxstr, name='MyCode'): del indx[0] indx.append(len(lyxstr)) edic = {} - exec 'from numpy import *' in edic - exec 'set_printoptions(linewidth=65)' in edic + exec('from numpy import *', edic) + exec('set_printoptions(linewidth=65)', edic) # indx now contains [st0,en0, ..., stN,enN] # where stX is the start of code segment X # and enX is the start of \layout MyCode for @@ -109,8 +112,8 @@ def runpycode(lyxstr, name='MyCode'): # if PYNEW found, then start a new namespace if mat: edic = {} - exec 'from numpy import *' in edic - exec 'set_printoptions(linewidth=65)' in edic + exec('from numpy import *', edic) + exec('set_printoptions(linewidth=65)', edic) # now find the code in the code segment # endoutput will contain the index just past any output # already present in the lyx string. diff --git a/doc/postprocess.py b/doc/postprocess.py index 1c6ef1b2e..512070193 100755 --- a/doc/postprocess.py +++ b/doc/postprocess.py @@ -6,6 +6,8 @@ Post-processes HTML and Latex files output by Sphinx. MODE is either 'html' or 'tex'. """ +from __future__ import division + import re, optparse def main(): diff --git a/doc/pyrex/run_test.py b/doc/pyrex/run_test.py index 96388011e..64918ed9c 100755 --- a/doc/pyrex/run_test.py +++ b/doc/pyrex/run_test.py @@ -1,3 +1,5 @@ #!/usr/bin/env python +from __future__ import division + from numpyx import test test() diff --git a/doc/pyrex/setup.py b/doc/pyrex/setup.py index 7f7cf0fc1..648bad9f4 100644 --- a/doc/pyrex/setup.py +++ b/doc/pyrex/setup.py @@ -10,7 +10,9 @@ Install file for example on how to use Pyrex with Numpy. For more details, see: http://www.scipy.org/Cookbook/Pyrex_and_NumPy http://www.scipy.org/Cookbook/ArrayStruct_and_Pyrex + """ +from __future__ import division from distutils.core import setup from distutils.extension import Extension diff --git a/doc/source/conf.py b/doc/source/conf.py index de9f6adf3..f22505f97 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from __future__ import division import sys, os, re @@ -20,24 +21,8 @@ sys.path.insert(0, os.path.abspath('../sphinxext')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.pngmath', 'numpydoc', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', - 'sphinx.ext.doctest', 'sphinx.ext.autosummary'] - -# Determine if the matplotlib has a recent enough version of the -# plot_directive, otherwise use the local fork. -try: - from matplotlib.sphinxext import plot_directive -except ImportError: - use_matplotlib_plot_directive = False -else: - try: - use_matplotlib_plot_directive = (plot_directive.__version__ >= 2) - except AttributeError: - use_matplotlib_plot_directive = False - -if use_matplotlib_plot_directive: - extensions.append('matplotlib.sphinxext.plot_directive') -else: - extensions.append('plot_directive') + 'sphinx.ext.doctest', 'sphinx.ext.autosummary', + 'matplotlib.sphinxext.plot_directive'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -61,7 +46,7 @@ version = re.sub(r'(\d+\.\d+)\.\d+(.*)', r'\1\2', numpy.__version__) version = re.sub(r'(\.dev\d+).*?$', r'\1', version) # The full version, including alpha/beta/rc tags. release = numpy.__version__ -print version, release +print("%s %s" % (version, release)) # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -215,6 +200,18 @@ latex_use_modindex = False # ----------------------------------------------------------------------------- +# Texinfo output +# ----------------------------------------------------------------------------- + +texinfo_documents = [ + ("contents", 'numpy', 'Numpy Documentation', _stdauthor, 'Numpy', + "NumPy: array processing for numbers, strings, records, and objects.", + 'Programming', + 1), +] + + +# ----------------------------------------------------------------------------- # Intersphinx configuration # ----------------------------------------------------------------------------- intersphinx_mapping = {'http://docs.python.org/dev': None} @@ -283,9 +280,6 @@ plot_rcparams = { 'text.usetex': False, } -if not use_matplotlib_plot_directive: - import matplotlib - matplotlib.rcParams.update(plot_rcparams) # ----------------------------------------------------------------------------- # Source code links @@ -294,7 +288,7 @@ if not use_matplotlib_plot_directive: import inspect from os.path import relpath, dirname -for name in ['sphinx.ext.linkcode', 'linkcode', 'numpydoc.linkcode']: +for name in ['sphinx.ext.linkcode', 'numpydoc.linkcode']: try: __import__(name) extensions.append(name) @@ -302,7 +296,7 @@ for name in ['sphinx.ext.linkcode', 'linkcode', 'numpydoc.linkcode']: except ImportError: pass else: - print "NOTE: linkcode extension not found -- no links to source generated" + print("NOTE: linkcode extension not found -- no links to source generated") def linkcode_resolve(domain, info): """ diff --git a/doc/source/reference/c-api.iterator.rst b/doc/source/reference/c-api.iterator.rst index 0915f765e..7e2900bcc 100644 --- a/doc/source/reference/c-api.iterator.rst +++ b/doc/source/reference/c-api.iterator.rst @@ -629,35 +629,6 @@ Construction and Destruction returns true from the corresponding element in the ARRAYMASK operand. - .. cvar:: NPY_ITER_USE_MASKNA - - .. versionadded:: 1.7 - - Adds a new operand to the end of the operand list which - iterates over the mask of this operand. If this operand has - no mask and is read-only, it broadcasts a constant - one-valued mask to indicate every value is valid. If this - operand has no mask and is writeable, an error is raised. - - Each operand which has this flag applied to it causes - an additional operand to be tacked on the end of the operand - list, in an order matching that of the operand array. - For example, if there are four operands, and operands with index - one and three have the flag :cdata:`NPY_ITER_USE_MASKNA` - specified, there will be six operands total, and they will - look like [op0, op1, op2, op3, op1_mask, op3_mask]. - - .. cvar:: NPY_ITER_IGNORE_MASKNA - - .. versionadded:: 1.7 - - Under some circumstances, code doing an iteration will - have already called :cfunc:`PyArray_ContainsNA` on an - operand which has a mask, and seen that its return value - was false. When this occurs, it is safe to do the iteration - without simultaneously iterating over the mask, and this - flag allows that to be done. - .. cfunction:: NpyIter* NpyIter_AdvancedNew(npy_intp nop, PyArrayObject** op, npy_uint32 flags, NPY_ORDER order, NPY_CASTING casting, npy_uint32* op_flags, PyArray_Descr** op_dtypes, int oa_ndim, int** op_axes, npy_intp* itershape, npy_intp buffersize) Extends :cfunc:`NpyIter_MultiNew` with several advanced options providing diff --git a/doc/sphinxext/MANIFEST.in b/doc/sphinxext/MANIFEST.in index f88ed785c..5176d485b 100644 --- a/doc/sphinxext/MANIFEST.in +++ b/doc/sphinxext/MANIFEST.in @@ -1,2 +1,2 @@ -recursive-include tests *.py +recursive-include numpydoc/tests *.py include *.txt diff --git a/doc/sphinxext/__init__.py b/doc/sphinxext/__init__.py deleted file mode 100644 index ae9073bc4..000000000 --- a/doc/sphinxext/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from numpydoc import setup diff --git a/doc/sphinxext/numpydoc/__init__.py b/doc/sphinxext/numpydoc/__init__.py new file mode 100644 index 000000000..68dbbb00a --- /dev/null +++ b/doc/sphinxext/numpydoc/__init__.py @@ -0,0 +1 @@ +from .numpydoc import setup diff --git a/doc/sphinxext/comment_eater.py b/doc/sphinxext/numpydoc/comment_eater.py index e11eea902..0e205072e 100644 --- a/doc/sphinxext/comment_eater.py +++ b/doc/sphinxext/numpydoc/comment_eater.py @@ -1,10 +1,17 @@ -from cStringIO import StringIO +from __future__ import division + +import sys +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO + import compiler import inspect import textwrap import tokenize -from compiler_unparse import unparse +from .compiler_unparse import unparse class Comment(object): @@ -68,7 +75,11 @@ class CommentBlocker(object): def process_file(self, file): """ Process a file object. """ - for token in tokenize.generate_tokens(file.next): + if sys.version_info[0] >= 3: + nxt = file.__next__ + else: + nxt = file.next + for token in tokenize.generate_tokens(nxt): self.process_token(*token) self.make_index() diff --git a/doc/sphinxext/compiler_unparse.py b/doc/sphinxext/numpydoc/compiler_unparse.py index ffcf51b35..56da748d1 100644 --- a/doc/sphinxext/compiler_unparse.py +++ b/doc/sphinxext/numpydoc/compiler_unparse.py @@ -10,13 +10,18 @@ fixme: We may want to move to using _ast trees because the compiler for them is about 6 times faster than compiler.compile. """ +from __future__ import division import sys -import cStringIO from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO + def unparse(ast, single_line_functions=False): - s = cStringIO.StringIO() + s = StringIO() UnparseCompilerAst(ast, s, single_line_functions) return s.getvalue().lstrip() diff --git a/doc/sphinxext/docscrape.py b/doc/sphinxext/numpydoc/docscrape.py index bbd3fcacc..0fe259447 100644 --- a/doc/sphinxext/docscrape.py +++ b/doc/sphinxext/numpydoc/docscrape.py @@ -1,13 +1,20 @@ """Extract reference documentation from the NumPy source tree. """ +from __future__ import division +import sys import inspect import textwrap import re import pydoc -from StringIO import StringIO from warnings import warn +import collections + +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO class Reader(object): """A line-based string reader. @@ -113,7 +120,7 @@ class NumpyDocString(object): return self._parsed_data[key] def __setitem__(self,key,val): - if not self._parsed_data.has_key(key): + if key not in self._parsed_data: warn("Unknown section %s" % key) else: self._parsed_data[key] = val @@ -265,13 +272,17 @@ class NumpyDocString(object): 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: + # If several signatures present, take the last one + while True: + 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(): + continue + break + + if summary is not None: self['Summary'] = summary if not self._is_at_section(): @@ -370,7 +381,7 @@ class NumpyDocString(object): idx = self['index'] out = [] out += ['.. index:: %s' % idx.get('default','')] - for section, references in idx.iteritems(): + for section, references in idx.items(): if section == 'default': continue out += [' :%s: %s' % (section, ', '.join(references))] @@ -428,7 +439,7 @@ class FunctionDoc(NumpyDocString): argspec = inspect.formatargspec(*argspec) argspec = argspec.replace('*','\*') signature = '%s%s' % (func_name, argspec) - except TypeError, e: + except TypeError as e: signature = '%s()' % func_name self['Signature'] = signature @@ -450,8 +461,8 @@ class FunctionDoc(NumpyDocString): 'meth': 'method'} if self._role: - if not roles.has_key(self._role): - print "Warning: invalid role %s" % self._role + if self._role not in roles: + print("Warning: invalid role %s" % self._role) out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), func_name) @@ -481,12 +492,19 @@ class ClassDoc(NumpyDocString): NumpyDocString.__init__(self, doc) if config.get('show_class_members', True): - if not self['Methods']: - self['Methods'] = [(name, '', '') - for name in sorted(self.methods)] - if not self['Attributes']: - self['Attributes'] = [(name, '', '') - for name in sorted(self.properties)] + def splitlines_x(s): + if not s: + return [] + else: + return s.splitlines() + + for field, items in [('Methods', self.methods), + ('Attributes', self.properties)]: + if not self[field]: + self[field] = [ + (name, '', + splitlines_x(pydoc.getdoc(getattr(self._cls, name)))) + for name in sorted(items)] @property def methods(self): @@ -495,11 +513,13 @@ class ClassDoc(NumpyDocString): return [name for name,func in inspect.getmembers(self._cls) if ((not name.startswith('_') or name in self.extra_public_methods) - and callable(func))] + and isinstance(func, collections.Callable))] @property def properties(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) - if not name.startswith('_') and func is None] + if not name.startswith('_') and + (func is None or isinstance(func, property) or + inspect.isgetsetdescriptor(func))] diff --git a/doc/sphinxext/docscrape_sphinx.py b/doc/sphinxext/numpydoc/docscrape_sphinx.py index e44e770ef..14d766d84 100644 --- a/doc/sphinxext/docscrape_sphinx.py +++ b/doc/sphinxext/numpydoc/docscrape_sphinx.py @@ -1,6 +1,9 @@ +from __future__ import division + import re, inspect, textwrap, pydoc import sphinx -from docscrape import NumpyDocString, FunctionDoc, ClassDoc +import collections +from .docscrape import NumpyDocString, FunctionDoc, ClassDoc class SphinxDocString(NumpyDocString): def __init__(self, docstring, config={}): @@ -72,7 +75,16 @@ class SphinxDocString(NumpyDocString): others = [] for param, param_type, desc in self[name]: param = param.strip() - if not self._obj or hasattr(self._obj, param): + + # Check if the referenced member can have a docstring or not + param_obj = getattr(self._obj, param, None) + if not (callable(param_obj) + or isinstance(param_obj, property) + or inspect.isgetsetdescriptor(param_obj)): + param_obj = None + + if param_obj and (pydoc.getdoc(param_obj) or not desc): + # Referenced object has a docstring autosum += [" %s%s" % (prefix, param)] else: others.append((param, param_type, desc)) @@ -82,15 +94,15 @@ class SphinxDocString(NumpyDocString): out += autosum if others: - maxlen_0 = max([len(x[0]) for x in others]) - maxlen_1 = max([len(x[1]) for x in others]) - hdr = "="*maxlen_0 + " " + "="*maxlen_1 + " " + "="*10 - fmt = '%%%ds %%%ds ' % (maxlen_0, maxlen_1) - n_indent = maxlen_0 + maxlen_1 + 4 - out += [hdr] + maxlen_0 = max(3, max([len(x[0]) for x in others])) + hdr = u"="*maxlen_0 + u" " + u"="*10 + fmt = u'%%%ds %%s ' % (maxlen_0,) + out += ['', hdr] for param, param_type, desc in others: - out += [fmt % (param.strip(), param_type)] - out += self._str_indent(desc, n_indent) + desc = u" ".join(x.strip() for x in desc).strip() + if param_type: + desc = "(%s) %s" % (param_type, desc) + out += [fmt % (param.strip(), desc)] out += [hdr] out += [''] return out @@ -127,7 +139,7 @@ class SphinxDocString(NumpyDocString): return out out += ['.. index:: %s' % idx.get('default','')] - for section, references in idx.iteritems(): + for section, references in idx.items(): if section == 'default': continue elif section == 'refguide': @@ -212,7 +224,7 @@ def get_doc_object(obj, what=None, doc=None, config={}): what = 'class' elif inspect.ismodule(obj): what = 'module' - elif callable(obj): + elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' diff --git a/doc/sphinxext/linkcode.py b/doc/sphinxext/numpydoc/linkcode.py index 1b1ef4a77..58361e8c3 100644 --- a/doc/sphinxext/linkcode.py +++ b/doc/sphinxext/numpydoc/linkcode.py @@ -7,11 +7,15 @@ :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. + """ +from __future__ import division import warnings -warnings.warn("This extension has been submitted to Sphinx upstream. " - "Use the version from there if it is accepted " +import collections + +warnings.warn("This extension has been accepted to Sphinx upstream. " + "Use the version from there (Sphinx >= 1.2) " "https://bitbucket.org/birkenfeld/sphinx/pull-request/47/sphinxextlinkcode", FutureWarning, stacklevel=1) @@ -29,7 +33,7 @@ def doctree_read(app, doctree): env = app.builder.env resolve_target = getattr(env.config, 'linkcode_resolve', None) - if not callable(env.config.linkcode_resolve): + if not isinstance(env.config.linkcode_resolve, collections.Callable): raise LinkcodeError( "Function `linkcode_resolve` is not given in conf.py") @@ -76,4 +80,4 @@ def doctree_read(app, doctree): def setup(app): app.connect('doctree-read', doctree_read) - app.add_config_value('linkcode_resolve', None, 'env') + app.add_config_value('linkcode_resolve', None, '') diff --git a/doc/sphinxext/numpydoc.py b/doc/sphinxext/numpydoc/numpydoc.py index 7679352c2..0243d23c4 100644 --- a/doc/sphinxext/numpydoc.py +++ b/doc/sphinxext/numpydoc/numpydoc.py @@ -15,14 +15,16 @@ It will: .. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt """ +from __future__ import division import sphinx +import collections if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") -import os, re, pydoc -from docscrape_sphinx import get_doc_object, SphinxDocString +import os, sys, re, pydoc +from .docscrape_sphinx import get_doc_object, SphinxDocString from sphinx.util.compat import Directive import inspect @@ -34,12 +36,16 @@ def mangle_docstrings(app, what, name, obj, options, lines, if what == 'module': # Strip top title - title_re = re.compile(ur'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*', + title_re = re.compile(u'^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*', re.I|re.S) lines[:] = title_re.sub(u'', u"\n".join(lines)).split(u"\n") else: doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg) - lines[:] = unicode(doc).split(u"\n") + if sys.version_info[0] >= 3: + doc = str(doc) + else: + doc = str(doc).decode('utf-8') + lines[:] = doc.split(u"\n") if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ obj.__name__: @@ -47,7 +53,7 @@ def mangle_docstrings(app, what, name, obj, options, lines, v = dict(full_name=u"%s.%s" % (obj.__module__, obj.__name__)) else: v = dict(full_name=obj.__name__) - lines += [u'', u'.. htmlonly::', ''] + lines += [u'', u'.. htmlonly::', u''] lines += [u' %s' % x for x in (app.config.numpydoc_edit_link % v).split("\n")] @@ -55,7 +61,7 @@ def mangle_docstrings(app, what, name, obj, options, lines, references = [] for line in lines: line = line.strip() - m = re.match(ur'^.. \[([a-z0-9_.-])\]', line, re.I) + m = re.match(u'^.. \\[([a-z0-9_.-])\\]', line, re.I) if m: references.append(m.group(1)) @@ -64,7 +70,7 @@ def mangle_docstrings(app, what, name, obj, options, lines, if references: for i, line in enumerate(lines): for r in references: - if re.match(ur'^\d+$', r): + if re.match(u'^\\d+$', r): new_r = u"R%d" % (reference_offset[0] + int(r)) else: new_r = u"%s%d" % (r, reference_offset[0]) @@ -82,7 +88,7 @@ def mangle_signature(app, what, name, obj, options, sig, retann): 'initializes x; see ' in pydoc.getdoc(obj.__init__))): return '', '' - if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return + if not (isinstance(obj, collections.Callable) or hasattr(obj, '__argspec_is_invalid_')): return if not hasattr(obj, '__doc__'): return doc = SphinxDocString(pydoc.getdoc(obj)) @@ -91,6 +97,9 @@ def mangle_signature(app, what, name, obj, options, sig, retann): return sig, u'' def setup(app, get_doc_object_=get_doc_object): + if not hasattr(app, 'add_config_value'): + return # probably called by nose, better bail out + global get_doc_object get_doc_object = get_doc_object_ @@ -120,7 +129,7 @@ class ManglingDomainBase(object): self.wrap_mangling_directives() def wrap_mangling_directives(self): - for name, objtype in self.directive_mangling_map.items(): + for name, objtype in list(self.directive_mangling_map.items()): self.directives[name] = wrap_mangling_directive( self.directives[name], objtype) diff --git a/doc/sphinxext/phantom_import.py b/doc/sphinxext/numpydoc/phantom_import.py index c77eeb544..6308f492d 100644 --- a/doc/sphinxext/phantom_import.py +++ b/doc/sphinxext/numpydoc/phantom_import.py @@ -14,6 +14,8 @@ without needing to rebuild the documented module. .. [1] http://code.google.com/p/pydocweb """ +from __future__ import division + import imp, sys, compiler, types, os, inspect, re def setup(app): @@ -23,7 +25,7 @@ def setup(app): def initialize(app): fn = app.config.phantom_import_file if (fn and os.path.isfile(fn)): - print "[numpydoc] Phantom importing modules from", fn, "..." + print("[numpydoc] Phantom importing modules from", fn, "...") import_phantom_module(fn) #------------------------------------------------------------------------------ @@ -129,7 +131,10 @@ def import_phantom_module(xml_file): doc = "%s%s\n\n%s" % (funcname, argspec, doc) obj = lambda: 0 obj.__argspec_is_invalid_ = True - obj.func_name = funcname + if sys.version_info[0] >= 3: + obj.__name__ = funcname + else: + obj.func_name = funcname obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): diff --git a/doc/sphinxext/plot_directive.py b/doc/sphinxext/numpydoc/plot_directive.py index 80801e798..7547642a2 100644 --- a/doc/sphinxext/plot_directive.py +++ b/doc/sphinxext/numpydoc/plot_directive.py @@ -36,7 +36,7 @@ The ``plot`` directive supports the options 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``. @@ -74,10 +74,16 @@ TODO to make them appear side-by-side, or in floats. """ +from __future__ import division -import sys, os, glob, shutil, imp, warnings, cStringIO, re, textwrap, traceback +import sys, os, glob, shutil, imp, warnings, re, textwrap, traceback import sphinx +if sys.version_info[0] >= 3: + from io import StringIO +else: + from cStringIO import StringIO + import warnings warnings.warn("A plot_directive module is also available under " "matplotlib.sphinxext; expect this numpydoc.plot_directive " @@ -94,7 +100,7 @@ def setup(app): setup.app = app setup.config = app.config setup.confdir = app.confdir - + app.add_config_value('plot_pre_code', '', True) app.add_config_value('plot_include_source', False, True) app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True) @@ -257,7 +263,7 @@ def run(arguments, content, options, state_machine, state, lineno): # is it in doctest format? is_doctest = contains_doctest(code) - if options.has_key('format'): + if 'format' in options: if options['format'] == 'python': is_doctest = False else: @@ -291,7 +297,7 @@ def run(arguments, content, options, state_machine, state, lineno): results = makefig(code, source_file_name, build_dir, output_base, config) errors = [] - except PlotError, err: + except PlotError as err: reporter = state.memo.reporter sm = reporter.system_message( 2, "Exception occurred in plotting %s: %s" % (output_base, err), @@ -314,7 +320,7 @@ def run(arguments, content, options, state_machine, state, lineno): else: source_code = "" - opts = [':%s: %s' % (key, val) for key, val in options.items() + opts = [':%s: %s' % (key, val) for key, val in list(options.items()) if key in ('alt', 'height', 'width', 'scale', 'align', 'class')] only_html = ".. only:: html" @@ -444,7 +450,7 @@ def run_code(code, code_path, ns=None): # Redirect stdout stdout = sys.stdout - sys.stdout = cStringIO.StringIO() + sys.stdout = StringIO() # Reset sys.argv old_sys_argv = sys.argv @@ -456,9 +462,9 @@ def run_code(code, code_path, ns=None): if ns is None: ns = {} if not ns: - exec setup.config.plot_pre_code in ns - exec code in ns - except (Exception, SystemExit), err: + exec(setup.config.plot_pre_code, ns) + exec(code, ns) + except (Exception, SystemExit) as err: raise PlotError(traceback.format_exc()) finally: os.chdir(pwd) @@ -520,7 +526,7 @@ def makefig(code, code_path, output_dir, output_base, config): all_exists = True for i, code_piece in enumerate(code_pieces): images = [] - for j in xrange(1000): + for j in range(1000): img = ImageFile('%s_%02d_%02d' % (output_base, i, j), output_dir) for format, dpi in formats: if out_of_date(code_path, img.filename(format)): @@ -565,7 +571,7 @@ def makefig(code, code_path, output_dir, output_base, config): for format, dpi in formats: try: figman.canvas.figure.savefig(img.filename(format), dpi=dpi) - except exceptions.BaseException, err: + except exceptions.BaseException as err: raise PlotError(traceback.format_exc()) img.formats.append(format) diff --git a/doc/sphinxext/tests/test_docscrape.py b/doc/sphinxext/numpydoc/tests/test_docscrape.py index 6fab79832..07ac68003 100644 --- a/doc/sphinxext/tests/test_docscrape.py +++ b/doc/sphinxext/numpydoc/tests/test_docscrape.py @@ -1,10 +1,10 @@ # -*- encoding:utf-8 -*- +from __future__ import division -import sys, os -sys.path.append(os.path.join(os.path.dirname(__file__), '..')) +import sys, textwrap -from docscrape import NumpyDocString, FunctionDoc, ClassDoc -from docscrape_sphinx import SphinxDocString, SphinxClassDoc +from numpydoc.docscrape import NumpyDocString, FunctionDoc, ClassDoc +from numpydoc.docscrape_sphinx import SphinxDocString, SphinxClassDoc from nose.tools import * doc_txt = '''\ @@ -165,11 +165,12 @@ def test_examples(): 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 = textwrap.dedent(a) + b = textwrap.dedent(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): @@ -556,7 +557,11 @@ def test_unicode(): äää """) - assert doc['Summary'][0] == u'öäöäöäöäöåååå'.encode('utf-8') + assert isinstance(doc['Summary'][0], str) + if sys.version_info[0] >= 3: + assert doc['Summary'][0] == u'öäöäöäöäöåååå' + else: + assert doc['Summary'][0] == u'öäöäöäöäöåååå'.encode('utf-8') def test_plot_examples(): cfg = dict(use_plots=True) @@ -594,20 +599,149 @@ def test_class_members(): def ham(self, c, d): """Cheese\n\nNo cheese.""" pass + @property + def spammity(self): + """Spammity index""" + return 0.95 + + class Ignorable(object): + """local class, to be ignored""" + pass for cls in (ClassDoc, SphinxClassDoc): doc = cls(Dummy, config=dict(show_class_members=False)) assert 'Methods' not in str(doc), (cls, str(doc)) assert 'spam' not in str(doc), (cls, str(doc)) assert 'ham' not in str(doc), (cls, str(doc)) + assert 'spammity' not in str(doc), (cls, str(doc)) + assert 'Spammity index' not in str(doc), (cls, str(doc)) doc = cls(Dummy, config=dict(show_class_members=True)) assert 'Methods' in str(doc), (cls, str(doc)) assert 'spam' in str(doc), (cls, str(doc)) assert 'ham' in str(doc), (cls, str(doc)) + assert 'spammity' in str(doc), (cls, str(doc)) if cls is SphinxClassDoc: assert '.. autosummary::' in str(doc), str(doc) + else: + assert 'Spammity index' in str(doc), str(doc) + +def test_duplicate_signature(): + # Duplicate function signatures occur e.g. in ufuncs, when the + # automatic mechanism adds one, and a more detailed comes from the + # docstring itself. + + doc = NumpyDocString( + """ + z(x1, x2) + + z(a, theta) + """) + + assert doc['Signature'].strip() == 'z(a, theta)' + + +class_doc_txt = """ + Foo + + Parameters + ---------- + f : callable ``f(t, y, *f_args)`` + Aaa. + jac : callable ``jac(t, y, *jac_args)`` + Bbb. + + Attributes + ---------- + t : float + Current time. + y : ndarray + Current variable values. + + Methods + ------- + a + b + c + + Examples + -------- + For usage examples, see `ode`. +""" + +def test_class_members_doc(): + doc = ClassDoc(None, class_doc_txt) + non_blank_line_by_line_compare(str(doc), + """ + Foo + + Parameters + ---------- + f : callable ``f(t, y, *f_args)`` + Aaa. + jac : callable ``jac(t, y, *jac_args)`` + Bbb. + + Examples + -------- + For usage examples, see `ode`. + + Attributes + ---------- + t : float + Current time. + y : ndarray + Current variable values. + + Methods + ------- + a : + + b : + + c : + + .. index:: + + """) + +def test_class_members_doc_sphinx(): + doc = SphinxClassDoc(None, class_doc_txt) + non_blank_line_by_line_compare(str(doc), + """ + Foo + + :Parameters: + + **f** : callable ``f(t, y, *f_args)`` + + Aaa. + + **jac** : callable ``jac(t, y, *jac_args)`` + + Bbb. + + .. rubric:: Examples + + For usage examples, see `ode`. + + .. rubric:: Attributes + + === ========== + t (float) Current time. + y (ndarray) Current variable values. + === ========== + + .. rubric:: Methods + + === ========== + a + b + c + === ========== + + """) if __name__ == "__main__": import nose diff --git a/doc/sphinxext/numpydoc/tests/test_linkcode.py b/doc/sphinxext/numpydoc/tests/test_linkcode.py new file mode 100644 index 000000000..45de6b70d --- /dev/null +++ b/doc/sphinxext/numpydoc/tests/test_linkcode.py @@ -0,0 +1,3 @@ +import numpydoc.linkcode + +# No tests at the moment... diff --git a/doc/sphinxext/numpydoc/tests/test_phantom_import.py b/doc/sphinxext/numpydoc/tests/test_phantom_import.py new file mode 100644 index 000000000..b9ee76fc6 --- /dev/null +++ b/doc/sphinxext/numpydoc/tests/test_phantom_import.py @@ -0,0 +1,3 @@ +import numpydoc.phantom_import + +# No tests at the moment... diff --git a/doc/sphinxext/numpydoc/tests/test_plot_directive.py b/doc/sphinxext/numpydoc/tests/test_plot_directive.py new file mode 100644 index 000000000..3496d2c29 --- /dev/null +++ b/doc/sphinxext/numpydoc/tests/test_plot_directive.py @@ -0,0 +1,3 @@ +import numpydoc.plot_directive + +# No tests at the moment... diff --git a/doc/sphinxext/numpydoc/tests/test_traitsdoc.py b/doc/sphinxext/numpydoc/tests/test_traitsdoc.py new file mode 100644 index 000000000..99b1600fb --- /dev/null +++ b/doc/sphinxext/numpydoc/tests/test_traitsdoc.py @@ -0,0 +1,3 @@ +import numpydoc.traitsdoc + +# No tests at the moment... diff --git a/doc/sphinxext/traitsdoc.py b/doc/sphinxext/numpydoc/traitsdoc.py index 0fcf2c1cd..784c4fc2f 100644 --- a/doc/sphinxext/traitsdoc.py +++ b/doc/sphinxext/numpydoc/traitsdoc.py @@ -13,18 +13,19 @@ for Traits is required. .. [2] http://code.enthought.com/projects/traits/ """ +from __future__ import division import inspect import os import pydoc -import docscrape -import docscrape_sphinx -from docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString +from . import docscrape +from . import docscrape_sphinx +from .docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString -import numpydoc +from . import numpydoc -import comment_eater +from . import comment_eater class SphinxTraitsDoc(SphinxClassDoc): def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc): @@ -117,7 +118,7 @@ def get_doc_object(obj, what=None, config=None): what = 'class' elif inspect.ismodule(obj): what = 'module' - elif callable(obj): + elif isinstance(obj, collections.Callable): what = 'function' else: what = 'object' diff --git a/doc/sphinxext/setup.py b/doc/sphinxext/setup.py index ec6aa3840..a6593aaa6 100644 --- a/doc/sphinxext/setup.py +++ b/doc/sphinxext/setup.py @@ -1,11 +1,18 @@ +from __future__ import division + +import setuptools from distutils.core import setup -version = "0.4" +import sys +if sys.version_info[0] >= 3 and sys.version_info[1] < 3 or \ + sys.version_info[0] <= 2 and sys.version_info[1] < 6: + raise RuntimeError("Python version 2.6, 2.7 or >= 3.3 required.") + +version = "0.4.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 @@ -20,4 +27,5 @@ setup( license="BSD", requires=["sphinx (>= 1.0.1)"], package_data={'numpydoc': ['tests/test_*.py']}, + test_suite = 'nose.collector', ) diff --git a/doc/summarize.py b/doc/summarize.py index cfaec6f7a..d953bd642 100755 --- a/doc/summarize.py +++ b/doc/summarize.py @@ -5,8 +5,10 @@ summarize.py Show a summary about which Numpy functions are documented and which are not. """ +from __future__ import division import os, glob, re, sys, inspect, optparse +import collections sys.path.append(os.path.join(os.path.dirname(__file__), 'sphinxext')) from sphinxext.phantom_import import import_phantom_module @@ -134,7 +136,7 @@ def get_undocumented(documented, module, module_name=None, skip=[]): if full_name in skip: continue if full_name.startswith('numpy.') and full_name[6:] in skip: continue - if not (inspect.ismodule(obj) or callable(obj) or inspect.isclass(obj)): + if not (inspect.ismodule(obj) or isinstance(obj, collections.Callable) or inspect.isclass(obj)): continue if full_name not in documented: diff --git a/doc/swig/test/setup.py b/doc/swig/test/setup.py index f2fc29aac..6395ffe46 100755 --- a/doc/swig/test/setup.py +++ b/doc/swig/test/setup.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.core import * diff --git a/doc/swig/test/testArray.py b/doc/swig/test/testArray.py index ba83d14d9..b25aff85a 100755 --- a/doc/swig/test/testArray.py +++ b/doc/swig/test/testArray.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform diff --git a/doc/swig/test/testFarray.py b/doc/swig/test/testFarray.py index 614e149bd..184fd2564 100755 --- a/doc/swig/test/testFarray.py +++ b/doc/swig/test/testFarray.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform diff --git a/doc/swig/test/testFortran.py b/doc/swig/test/testFortran.py index d2c382869..56bc03eae 100644 --- a/doc/swig/test/testFortran.py +++ b/doc/swig/test/testFortran.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform diff --git a/doc/swig/test/testMatrix.py b/doc/swig/test/testMatrix.py index 12061702d..68259de3e 100755 --- a/doc/swig/test/testMatrix.py +++ b/doc/swig/test/testMatrix.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform diff --git a/doc/swig/test/testTensor.py b/doc/swig/test/testTensor.py index 3d0ce097e..41b037811 100755 --- a/doc/swig/test/testTensor.py +++ b/doc/swig/test/testTensor.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform diff --git a/doc/swig/test/testVector.py b/doc/swig/test/testVector.py index 2ee918389..2ad00b856 100755 --- a/doc/swig/test/testVector.py +++ b/doc/swig/test/testVector.py @@ -1,4 +1,5 @@ #! /usr/bin/env python +from __future__ import division # System imports from distutils.util import get_platform |