mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'master' into ignore__all__
This commit is contained in:
commit
ffa9d48d0e
8
CHANGES
8
CHANGES
@ -49,7 +49,9 @@ Features added
|
|||||||
* HTML themes can set up default sidebars through ``theme.conf``
|
* HTML themes can set up default sidebars through ``theme.conf``
|
||||||
* #3160: html: Use ``<kdb>`` to represent ``:kbd:`` role
|
* #3160: html: Use ``<kdb>`` to represent ``:kbd:`` role
|
||||||
* #4212: autosummary: catch all exceptions when importing modules
|
* #4212: autosummary: catch all exceptions when importing modules
|
||||||
* #3991, #4080: Add :confval:`math_numfig` for equation numbering by section
|
* #4166: Add :confval:`math_numfig` for equation numbering by section (refs:
|
||||||
|
#3991, #4080). Thanks to Oliver Jahn.
|
||||||
|
* #4311: Let LaTeX obey :confval:`numfig_secnum_depth` for figures, tables, ...
|
||||||
* #947: autodoc now supports ignore-module-all to ignore a module's ``__all__``
|
* #947: autodoc now supports ignore-module-all to ignore a module's ``__all__``
|
||||||
|
|
||||||
|
|
||||||
@ -92,6 +94,8 @@ Bugs fixed
|
|||||||
* #4094: C++, allow empty template argument lists.
|
* #4094: C++, allow empty template argument lists.
|
||||||
* C++, also hyperlink types in the name of declarations with qualified names.
|
* C++, also hyperlink types in the name of declarations with qualified names.
|
||||||
* C++, do not add index entries for declarations inside concepts.
|
* C++, do not add index entries for declarations inside concepts.
|
||||||
|
* #4314: For PDF 'howto' documents, numbering of code-blocks differs from the
|
||||||
|
one of figures and tables
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
@ -134,6 +138,8 @@ Bugs fixed
|
|||||||
remote image
|
remote image
|
||||||
* #1421: Respect the quiet flag in sphinx-quickstart
|
* #1421: Respect the quiet flag in sphinx-quickstart
|
||||||
* #4281: Race conditions when creating output directory
|
* #4281: Race conditions when creating output directory
|
||||||
|
* #4315: For PDF 'howto' documents, ``latex_toplevel_sectioning='part'`` generates
|
||||||
|
``\chapter`` commands
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
--------
|
--------
|
||||||
|
1
EXAMPLES
1
EXAMPLES
@ -141,6 +141,7 @@ Documentation using the nature theme
|
|||||||
Documentation using another builtin theme
|
Documentation using another builtin theme
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
|
* Arcade: http://arcade.academy/ (sphinx_rtd_theme)
|
||||||
* Breathe: https://breathe.readthedocs.io/ (haiku)
|
* Breathe: https://breathe.readthedocs.io/ (haiku)
|
||||||
* MPipe: https://vmlaker.github.io/mpipe/ (sphinx13)
|
* MPipe: https://vmlaker.github.io/mpipe/ (sphinx13)
|
||||||
* NLTK: http://www.nltk.org/ (agogo)
|
* NLTK: http://www.nltk.org/ (agogo)
|
||||||
|
@ -341,20 +341,19 @@ General configuration
|
|||||||
starting at ``1``.
|
starting at ``1``.
|
||||||
- if ``1`` (default) numbers will be ``x.1``, ``x.2``, ... with ``x``
|
- if ``1`` (default) numbers will be ``x.1``, ``x.2``, ... with ``x``
|
||||||
the section number (top level sectioning; no ``x.`` if no section).
|
the section number (top level sectioning; no ``x.`` if no section).
|
||||||
This naturally applies only if section numbering has been activated via
|
This naturally applies only if section numbering has been activated via
|
||||||
the ``:numbered:`` option of the :rst:dir:`toctree` directive.
|
the ``:numbered:`` option of the :rst:dir:`toctree` directive.
|
||||||
- ``2`` means that numbers will be ``x.y.1``, ``x.y.2``, ... if located in
|
- ``2`` means that numbers will be ``x.y.1``, ``x.y.2``, ... if located in
|
||||||
a sub-section (but still ``x.1``, ``x.2``, ... if located directly under a
|
a sub-section (but still ``x.1``, ``x.2``, ... if located directly under a
|
||||||
section and ``1``, ``2``, ... if not in any top level section.)
|
section and ``1``, ``2``, ... if not in any top level section.)
|
||||||
- etc...
|
- etc...
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The LaTeX builder currently ignores this configuration setting. It will
|
|
||||||
obey it at Sphinx 1.7.
|
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
The LaTeX builder obeys this setting (if :confval:`numfig` is set to
|
||||||
|
``True``).
|
||||||
|
|
||||||
.. confval:: tls_verify
|
.. confval:: tls_verify
|
||||||
|
|
||||||
If true, Sphinx verifies server certifications. Default is ``True``.
|
If true, Sphinx verifies server certifications. Default is ``True``.
|
||||||
@ -1624,10 +1623,15 @@ These options influence LaTeX output. See further :doc:`latex`.
|
|||||||
.. confval:: latex_toplevel_sectioning
|
.. confval:: latex_toplevel_sectioning
|
||||||
|
|
||||||
This value determines the topmost sectioning unit. It should be chosen from
|
This value determines the topmost sectioning unit. It should be chosen from
|
||||||
``part``, ``chapter`` or ``section``. The default is ``None``; the topmost
|
``'part'``, ``'chapter'`` or ``'section'``. The default is ``None``;
|
||||||
sectioning unit is switched by documentclass. ``section`` is used if
|
the topmost
|
||||||
|
sectioning unit is switched by documentclass: ``section`` is used if
|
||||||
documentclass will be ``howto``, otherwise ``chapter`` will be used.
|
documentclass will be ``howto``, otherwise ``chapter`` will be used.
|
||||||
|
|
||||||
|
Note that if LaTeX uses ``\part`` command, then the numbering of sectioning
|
||||||
|
units one level deep gets off-sync with HTML numbering, because LaTeX
|
||||||
|
numbers continuously ``\chapter`` (or ``\section`` for ``howto``.)
|
||||||
|
|
||||||
.. versionadded:: 1.4
|
.. versionadded:: 1.4
|
||||||
|
|
||||||
.. confval:: latex_appendices
|
.. confval:: latex_appendices
|
||||||
|
@ -183,7 +183,7 @@
|
|||||||
% control caption around literal-block
|
% control caption around literal-block
|
||||||
\RequirePackage{capt-of}
|
\RequirePackage{capt-of}
|
||||||
\RequirePackage{needspace}
|
\RequirePackage{needspace}
|
||||||
|
\RequirePackage{remreset}% provides \@removefromreset
|
||||||
% to make pdf with correct encoded bookmarks in Japanese
|
% to make pdf with correct encoded bookmarks in Japanese
|
||||||
% this should precede the hyperref package
|
% this should precede the hyperref package
|
||||||
\ifx\kanjiskip\@undefined
|
\ifx\kanjiskip\@undefined
|
||||||
@ -247,7 +247,9 @@
|
|||||||
\fi
|
\fi
|
||||||
|
|
||||||
\DeclareStringOption[0]{maxlistdepth}% \newcommand*\spx@opt@maxlistdepth{0}
|
\DeclareStringOption[0]{maxlistdepth}% \newcommand*\spx@opt@maxlistdepth{0}
|
||||||
|
\DeclareStringOption[-1]{numfigreset}
|
||||||
|
\DeclareBoolOption[false]{nonumfigreset}
|
||||||
|
% \DeclareBoolOption[false]{usespart}% not used
|
||||||
% dimensions, we declare the \dimen registers here.
|
% dimensions, we declare the \dimen registers here.
|
||||||
\newdimen\sphinxverbatimsep
|
\newdimen\sphinxverbatimsep
|
||||||
\newdimen\sphinxverbatimborder
|
\newdimen\sphinxverbatimborder
|
||||||
@ -349,6 +351,8 @@
|
|||||||
\ProcessKeyvalOptions*
|
\ProcessKeyvalOptions*
|
||||||
% don't allow use of maxlistdepth via \sphinxsetup.
|
% don't allow use of maxlistdepth via \sphinxsetup.
|
||||||
\DisableKeyvalOption{sphinx}{maxlistdepth}
|
\DisableKeyvalOption{sphinx}{maxlistdepth}
|
||||||
|
\DisableKeyvalOption{sphinx}{numfigreset}
|
||||||
|
\DisableKeyvalOption{sphinx}{nonumfigreset}
|
||||||
% user interface: options can be changed midway in a document!
|
% user interface: options can be changed midway in a document!
|
||||||
\newcommand\sphinxsetup[1]{\setkeys{sphinx}{#1}}
|
\newcommand\sphinxsetup[1]{\setkeys{sphinx}{#1}}
|
||||||
|
|
||||||
@ -657,6 +661,7 @@
|
|||||||
{\abovecaptionskip\smallskipamount
|
{\abovecaptionskip\smallskipamount
|
||||||
\belowcaptionskip\smallskipamount}
|
\belowcaptionskip\smallskipamount}
|
||||||
|
|
||||||
|
|
||||||
%% FOOTNOTES
|
%% FOOTNOTES
|
||||||
%
|
%
|
||||||
% Support large numbered footnotes in minipage
|
% Support large numbered footnotes in minipage
|
||||||
@ -665,6 +670,87 @@
|
|||||||
\def\thempfootnote{\arabic{mpfootnote}}
|
\def\thempfootnote{\arabic{mpfootnote}}
|
||||||
|
|
||||||
|
|
||||||
|
%% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS
|
||||||
|
\ltx@ifundefined{c@chapter}
|
||||||
|
{\newcounter{literalblock}}%
|
||||||
|
{\newcounter{literalblock}[chapter]%
|
||||||
|
\def\theliteralblock{\ifnum\c@chapter>\z@\arabic{chapter}.\fi
|
||||||
|
\arabic{literalblock}}%
|
||||||
|
}%
|
||||||
|
\ifspx@opt@nonumfigreset
|
||||||
|
\ltx@ifundefined{c@chapter}{}{%
|
||||||
|
\@removefromreset{figure}{chapter}%
|
||||||
|
\@removefromreset{table}{chapter}%
|
||||||
|
\@removefromreset{literalblock}{chapter}%
|
||||||
|
}%
|
||||||
|
\def\thefigure{\arabic{figure}}%
|
||||||
|
\def\thetable {\arabic{table}}%
|
||||||
|
\def\theliteralblock{\arabic{literalblock}}%
|
||||||
|
%\let\theHliteralblock\theliteralblock
|
||||||
|
\else
|
||||||
|
\let\spx@preAthefigure\@empty
|
||||||
|
\let\spx@preBthefigure\@empty
|
||||||
|
% \ifspx@opt@usespart % <-- LaTeX writer could pass such a 'usespart' boolean
|
||||||
|
% % as sphinx.sty package option
|
||||||
|
% If document uses \part, (triggered in Sphinx by latex_toplevel_sectioning)
|
||||||
|
% LaTeX core per default does not reset chapter or section
|
||||||
|
% counters at each part.
|
||||||
|
% But if we modify this, we need to redefine \thechapter, \thesection to
|
||||||
|
% include the part number and this will cause problems in table of contents
|
||||||
|
% because of too wide numbering. Simplest is to do nothing.
|
||||||
|
% \fi
|
||||||
|
\ifnum\spx@opt@numfigreset>0
|
||||||
|
\ltx@ifundefined{c@chapter}
|
||||||
|
{}
|
||||||
|
{\g@addto@macro\spx@preAthefigure{\ifnum\c@chapter>\z@\arabic{chapter}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}}%
|
||||||
|
\fi
|
||||||
|
\ifnum\spx@opt@numfigreset>1
|
||||||
|
\@addtoreset{figure}{section}%
|
||||||
|
\@addtoreset{table}{section}%
|
||||||
|
\@addtoreset{literalblock}{section}%
|
||||||
|
\g@addto@macro\spx@preAthefigure{\ifnum\c@section>\z@\arabic{section}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}%
|
||||||
|
\fi
|
||||||
|
\ifnum\spx@opt@numfigreset>2
|
||||||
|
\@addtoreset{figure}{subsection}%
|
||||||
|
\@addtoreset{table}{subsection}%
|
||||||
|
\@addtoreset{literalblock}{subsection}%
|
||||||
|
\g@addto@macro\spx@preAthefigure{\ifnum\c@subsection>\z@\arabic{subsection}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}%
|
||||||
|
\fi
|
||||||
|
\ifnum\spx@opt@numfigreset>3
|
||||||
|
\@addtoreset{figure}{subsubsection}%
|
||||||
|
\@addtoreset{table}{subsubsection}%
|
||||||
|
\@addtoreset{literalblock}{subsubsection}%
|
||||||
|
\g@addto@macro\spx@preAthefigure{\ifnum\c@subsubsection>\z@\arabic{subsubsection}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}%
|
||||||
|
\fi
|
||||||
|
\ifnum\spx@opt@numfigreset>4
|
||||||
|
\@addtoreset{figure}{paragraph}%
|
||||||
|
\@addtoreset{table}{paragraph}%
|
||||||
|
\@addtoreset{literalblock}{paragraph}%
|
||||||
|
\g@addto@macro\spx@preAthefigure{\ifnum\c@subparagraph>\z@\arabic{subparagraph}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}%
|
||||||
|
\fi
|
||||||
|
\ifnum\spx@opt@numfigreset>5
|
||||||
|
\@addtoreset{figure}{subparagraph}%
|
||||||
|
\@addtoreset{table}{subparagraph}%
|
||||||
|
\@addtoreset{literalblock}{subparagraph}%
|
||||||
|
\g@addto@macro\spx@preAthefigure{\ifnum\c@subsubparagraph>\z@\arabic{subsubparagraph}.}%
|
||||||
|
\g@addto@macro\spx@preBthefigure{\fi}%
|
||||||
|
\fi
|
||||||
|
\expandafter\g@addto@macro
|
||||||
|
\expandafter\spx@preAthefigure\expandafter{\spx@preBthefigure}%
|
||||||
|
\let\thefigure\spx@preAthefigure
|
||||||
|
\let\thetable\spx@preAthefigure
|
||||||
|
\let\theliteralblock\spx@preAthefigure
|
||||||
|
\g@addto@macro\thefigure{\arabic{figure}}%
|
||||||
|
\g@addto@macro\thetable{\arabic{table}}%
|
||||||
|
\g@addto@macro\theliteralblock{\arabic{literalblock}}%
|
||||||
|
\fi
|
||||||
|
|
||||||
|
|
||||||
%% LITERAL BLOCKS
|
%% LITERAL BLOCKS
|
||||||
%
|
%
|
||||||
% Based on use of "fancyvrb.sty"'s Verbatim.
|
% Based on use of "fancyvrb.sty"'s Verbatim.
|
||||||
@ -680,15 +766,6 @@
|
|||||||
\let\endOriginalVerbatim\endVerbatim
|
\let\endOriginalVerbatim\endVerbatim
|
||||||
|
|
||||||
% for captions of literal blocks
|
% for captions of literal blocks
|
||||||
% also define `\theH...` macros for hyperref
|
|
||||||
\newcounter{literalblock}
|
|
||||||
\ltx@ifundefined{c@chapter}
|
|
||||||
{\@addtoreset{literalblock}{section}
|
|
||||||
\def\theliteralblock {\ifnum\c@section>\z@ \thesection.\fi\arabic{literalblock}}
|
|
||||||
\def\theHliteralblock {\theHsection.\arabic{literalblock}}}
|
|
||||||
{\@addtoreset{literalblock}{chapter}
|
|
||||||
\def\theliteralblock {\ifnum\c@chapter>\z@ \thechapter.\fi\arabic{literalblock}}
|
|
||||||
\def\theHliteralblock {\theHchapter.\arabic{literalblock}}}
|
|
||||||
% at start of caption title
|
% at start of caption title
|
||||||
\newcommand*{\fnum@literalblock}{\literalblockname\nobreakspace\theliteralblock}
|
\newcommand*{\fnum@literalblock}{\literalblockname\nobreakspace\theliteralblock}
|
||||||
% this will be overwritten in document preamble by Babel translation
|
% this will be overwritten in document preamble by Babel translation
|
||||||
|
@ -48,7 +48,8 @@ BEGIN_DOC = r'''
|
|||||||
|
|
||||||
|
|
||||||
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
|
||||||
SECNUMDEPTH = 3
|
LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
|
||||||
|
"subsubsection", "paragraph", "subparagraph"]
|
||||||
|
|
||||||
DEFAULT_SETTINGS = {
|
DEFAULT_SETTINGS = {
|
||||||
'latex_engine': 'pdflatex',
|
'latex_engine': 'pdflatex',
|
||||||
@ -501,9 +502,9 @@ def rstdim_to_latexdim(width_str):
|
|||||||
|
|
||||||
|
|
||||||
class LaTeXTranslator(nodes.NodeVisitor):
|
class LaTeXTranslator(nodes.NodeVisitor):
|
||||||
sectionnames = ["part", "chapter", "section", "subsection",
|
|
||||||
"subsubsection", "paragraph", "subparagraph"]
|
|
||||||
|
|
||||||
|
secnumdepth = 2 # legacy sphinxhowto.cls uses this, whereas article.cls
|
||||||
|
# default is originally 3. For book/report, 2 is already LaTeX default.
|
||||||
ignore_missing_images = False
|
ignore_missing_images = False
|
||||||
|
|
||||||
# sphinx specific document classes
|
# sphinx specific document classes
|
||||||
@ -532,16 +533,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.compact_list = 0
|
self.compact_list = 0
|
||||||
self.first_param = 0
|
self.first_param = 0
|
||||||
|
|
||||||
# determine top section level
|
|
||||||
if builder.config.latex_toplevel_sectioning:
|
|
||||||
self.top_sectionlevel = \
|
|
||||||
self.sectionnames.index(builder.config.latex_toplevel_sectioning)
|
|
||||||
else:
|
|
||||||
if document.settings.docclass == 'howto':
|
|
||||||
self.top_sectionlevel = 2
|
|
||||||
else:
|
|
||||||
self.top_sectionlevel = 1
|
|
||||||
|
|
||||||
# sort out some elements
|
# sort out some elements
|
||||||
self.elements = DEFAULT_SETTINGS.copy()
|
self.elements = DEFAULT_SETTINGS.copy()
|
||||||
self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {}))
|
self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {}))
|
||||||
@ -562,16 +553,55 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
self.elements.update({
|
self.elements.update({
|
||||||
'releasename': _('Release'),
|
'releasename': _('Release'),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# we assume LaTeX class provides \chapter command except in case
|
||||||
|
# of non-Japanese 'howto' case
|
||||||
|
self.sectionnames = LATEXSECTIONNAMES[:]
|
||||||
if document.settings.docclass == 'howto':
|
if document.settings.docclass == 'howto':
|
||||||
docclass = builder.config.latex_docclass.get('howto', 'article')
|
docclass = builder.config.latex_docclass.get('howto', 'article')
|
||||||
|
if docclass[0] == 'j': # Japanese class...
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.sectionnames.remove('chapter')
|
||||||
else:
|
else:
|
||||||
docclass = builder.config.latex_docclass.get('manual', 'report')
|
docclass = builder.config.latex_docclass.get('manual', 'report')
|
||||||
self.elements['docclass'] = docclass
|
self.elements['docclass'] = docclass
|
||||||
|
|
||||||
|
# determine top section level
|
||||||
|
self.top_sectionlevel = 1
|
||||||
|
if builder.config.latex_toplevel_sectioning:
|
||||||
|
try:
|
||||||
|
self.top_sectionlevel = \
|
||||||
|
self.sectionnames.index(builder.config.latex_toplevel_sectioning)
|
||||||
|
except ValueError:
|
||||||
|
logger.warning('unknown %r toplevel_sectioning for class %r' %
|
||||||
|
(builder.config.latex_toplevel_sectioning, docclass))
|
||||||
|
|
||||||
if builder.config.today:
|
if builder.config.today:
|
||||||
self.elements['date'] = builder.config.today
|
self.elements['date'] = builder.config.today
|
||||||
else:
|
else:
|
||||||
self.elements['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), # type: ignore # NOQA
|
self.elements['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), # type: ignore # NOQA
|
||||||
language=builder.config.language)
|
language=builder.config.language)
|
||||||
|
|
||||||
|
if builder.config.numfig:
|
||||||
|
self.numfig_secnum_depth = builder.config.numfig_secnum_depth
|
||||||
|
if self.numfig_secnum_depth > 0: # default is 1
|
||||||
|
# numfig_secnum_depth as passed to sphinx.sty indices same names as in
|
||||||
|
# LATEXSECTIONNAMES but with -1 for part, 0 for chapter, 1 for section...
|
||||||
|
if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
|
||||||
|
self.top_sectionlevel > 0:
|
||||||
|
self.numfig_secnum_depth += self.top_sectionlevel
|
||||||
|
else:
|
||||||
|
self.numfig_secnum_depth += self.top_sectionlevel - 1
|
||||||
|
# this (minus one) will serve as minimum to LaTeX's secnumdepth
|
||||||
|
self.numfig_secnum_depth = min(self.numfig_secnum_depth,
|
||||||
|
len(LATEXSECTIONNAMES) - 1)
|
||||||
|
# if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty
|
||||||
|
self.elements['sphinxpkgoptions'] += \
|
||||||
|
(',numfigreset=%s' % self.numfig_secnum_depth)
|
||||||
|
else:
|
||||||
|
self.elements['sphinxpkgoptions'] += ',nonumfigreset'
|
||||||
|
|
||||||
if builder.config.latex_logo:
|
if builder.config.latex_logo:
|
||||||
# no need for \\noindent here, used in flushright
|
# no need for \\noindent here, used in flushright
|
||||||
self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \
|
self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \
|
||||||
@ -628,23 +658,32 @@ class LaTeXTranslator(nodes.NodeVisitor):
|
|||||||
return '\\usepackage{%s}' % (packagename,)
|
return '\\usepackage{%s}' % (packagename,)
|
||||||
usepackages = (declare_package(*p) for p in builder.usepackages)
|
usepackages = (declare_package(*p) for p in builder.usepackages)
|
||||||
self.elements['usepackages'] += "\n".join(usepackages)
|
self.elements['usepackages'] += "\n".join(usepackages)
|
||||||
|
|
||||||
|
minsecnumdepth = self.secnumdepth # 2 from legacy sphinx manual/howto
|
||||||
if document.get('tocdepth'):
|
if document.get('tocdepth'):
|
||||||
# redece tocdepth if `part` or `chapter` is used for top_sectionlevel
|
# reduce tocdepth if `part` or `chapter` is used for top_sectionlevel
|
||||||
# tocdepth = -1: show only parts
|
# tocdepth = -1: show only parts
|
||||||
# tocdepth = 0: show parts and chapters
|
# tocdepth = 0: show parts and chapters
|
||||||
# tocdepth = 1: show parts, chapters and sections
|
# tocdepth = 1: show parts, chapters and sections
|
||||||
# tocdepth = 2: show parts, chapters, sections and subsections
|
# tocdepth = 2: show parts, chapters, sections and subsections
|
||||||
# ...
|
# ...
|
||||||
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
|
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
|
||||||
maxdepth = len(self.sectionnames) - self.top_sectionlevel
|
if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
|
||||||
if tocdepth > maxdepth:
|
self.top_sectionlevel > 0:
|
||||||
|
tocdepth += 1 # because top_sectionlevel is shifted by -1
|
||||||
|
if tocdepth > len(LATEXSECTIONNAMES) - 2: # default is 5 <-> subparagraph
|
||||||
logger.warning('too large :maxdepth:, ignored.')
|
logger.warning('too large :maxdepth:, ignored.')
|
||||||
tocdepth = maxdepth
|
tocdepth = len(LATEXSECTIONNAMES) - 2
|
||||||
|
|
||||||
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
|
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
|
||||||
if tocdepth >= SECNUMDEPTH:
|
minsecnumdepth = max(minsecnumdepth, tocdepth)
|
||||||
# Increase secnumdepth if tocdepth is depther than default SECNUMDEPTH
|
|
||||||
self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' % tocdepth
|
if builder.config.numfig and (builder.config.numfig_secnum_depth > 0):
|
||||||
|
minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1)
|
||||||
|
|
||||||
|
if minsecnumdepth > self.secnumdepth:
|
||||||
|
self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\
|
||||||
|
minsecnumdepth
|
||||||
|
|
||||||
if getattr(document.settings, 'contentsname', None):
|
if getattr(document.settings, 'contentsname', None):
|
||||||
self.elements['contentsname'] = \
|
self.elements['contentsname'] = \
|
||||||
|
225
tests/roots/test-ext-autodoc/target/__init__.py
Normal file
225
tests/roots/test-ext-autodoc/target/__init__.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import enum
|
||||||
|
from six import StringIO, add_metaclass
|
||||||
|
from sphinx.ext.autodoc import add_documenter # NOQA
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Class']
|
||||||
|
|
||||||
|
#: documentation for the integer
|
||||||
|
integer = 1
|
||||||
|
|
||||||
|
|
||||||
|
def raises(exc, func, *args, **kwds):
|
||||||
|
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomEx(Exception):
|
||||||
|
"""My custom exception."""
|
||||||
|
|
||||||
|
def f(self):
|
||||||
|
"""Exception method."""
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDataDescriptor(object):
|
||||||
|
"""Descriptor class docstring."""
|
||||||
|
|
||||||
|
def __init__(self, doc):
|
||||||
|
self.__doc__ = doc
|
||||||
|
|
||||||
|
def __get__(self, obj, type=None):
|
||||||
|
if obj is None:
|
||||||
|
return self
|
||||||
|
return 42
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Function."""
|
||||||
|
return "The Answer"
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDataDescriptorMeta(type):
|
||||||
|
"""Descriptor metaclass docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
@add_metaclass(CustomDataDescriptorMeta)
|
||||||
|
class CustomDataDescriptor2(CustomDataDescriptor):
|
||||||
|
"""Descriptor class with custom metaclass docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
def _funky_classmethod(name, b, c, d, docstring=None):
|
||||||
|
"""Generates a classmethod for a class from a template by filling out
|
||||||
|
some arguments."""
|
||||||
|
def template(cls, a, b, c, d=4, e=5, f=6):
|
||||||
|
return a, b, c, d, e, f
|
||||||
|
from functools import partial
|
||||||
|
function = partial(template, b=b, c=c, d=d)
|
||||||
|
function.__name__ = name
|
||||||
|
function.__doc__ = docstring
|
||||||
|
return classmethod(function)
|
||||||
|
|
||||||
|
|
||||||
|
class Base(object):
|
||||||
|
def inheritedmeth(self):
|
||||||
|
"""Inherited function."""
|
||||||
|
|
||||||
|
|
||||||
|
class Derived(Base):
|
||||||
|
def inheritedmeth(self):
|
||||||
|
# no docstring here
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Class(Base):
|
||||||
|
"""Class to document."""
|
||||||
|
|
||||||
|
descr = CustomDataDescriptor("Descriptor instance docstring.")
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Function."""
|
||||||
|
|
||||||
|
def undocmeth(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def skipmeth(self):
|
||||||
|
"""Method that should be skipped."""
|
||||||
|
|
||||||
|
def excludemeth(self):
|
||||||
|
"""Method that should be excluded."""
|
||||||
|
|
||||||
|
# should not be documented
|
||||||
|
skipattr = 'foo'
|
||||||
|
|
||||||
|
#: should be documented -- süß
|
||||||
|
attr = 'bar'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop(self):
|
||||||
|
"""Property."""
|
||||||
|
|
||||||
|
docattr = 'baz'
|
||||||
|
"""should likewise be documented -- süß"""
|
||||||
|
|
||||||
|
udocattr = 'quux'
|
||||||
|
u"""should be documented as well - süß"""
|
||||||
|
|
||||||
|
# initialized to any class imported from another module
|
||||||
|
mdocattr = StringIO()
|
||||||
|
"""should be documented as well - süß"""
|
||||||
|
|
||||||
|
roger = _funky_classmethod("roger", 2, 3, 4)
|
||||||
|
|
||||||
|
moore = _funky_classmethod("moore", 9, 8, 7,
|
||||||
|
docstring="moore(a, e, f) -> happiness")
|
||||||
|
|
||||||
|
def __init__(self, arg):
|
||||||
|
self.inst_attr_inline = None #: an inline documented instance attr
|
||||||
|
#: a documented instance attribute
|
||||||
|
self.inst_attr_comment = None
|
||||||
|
self.inst_attr_string = None
|
||||||
|
"""a documented instance attribute"""
|
||||||
|
self._private_inst_attr = None #: a private instance attribute
|
||||||
|
|
||||||
|
def __special1__(self):
|
||||||
|
"""documented special method"""
|
||||||
|
|
||||||
|
def __special2__(self):
|
||||||
|
# undocumented special method
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDict(dict):
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
def function(foo, *args, **kwds):
|
||||||
|
"""
|
||||||
|
Return spam.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Outer(object):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
class Inner(object):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
# should be documented as an alias
|
||||||
|
factory = dict
|
||||||
|
|
||||||
|
|
||||||
|
class DocstringSig(object):
|
||||||
|
def meth(self):
|
||||||
|
"""meth(FOO, BAR=1) -> BAZ
|
||||||
|
First line of docstring
|
||||||
|
|
||||||
|
rest of docstring
|
||||||
|
"""
|
||||||
|
|
||||||
|
def meth2(self):
|
||||||
|
"""First line, no signature
|
||||||
|
Second line followed by indentation::
|
||||||
|
|
||||||
|
indented line
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop1(self):
|
||||||
|
"""DocstringSig.prop1(self)
|
||||||
|
First line of docstring
|
||||||
|
"""
|
||||||
|
return 123
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop2(self):
|
||||||
|
"""First line of docstring
|
||||||
|
Second line of docstring
|
||||||
|
"""
|
||||||
|
return 456
|
||||||
|
|
||||||
|
|
||||||
|
class StrRepr(str):
|
||||||
|
def __repr__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class AttCls(object):
|
||||||
|
a1 = StrRepr('hello\nworld')
|
||||||
|
a2 = None
|
||||||
|
|
||||||
|
|
||||||
|
class InstAttCls(object):
|
||||||
|
"""Class with documented class and instance attributes."""
|
||||||
|
|
||||||
|
#: Doc comment for class attribute InstAttCls.ca1.
|
||||||
|
#: It can have multiple lines.
|
||||||
|
ca1 = 'a'
|
||||||
|
|
||||||
|
ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
|
||||||
|
|
||||||
|
ca3 = 'c'
|
||||||
|
"""Docstring for class attribute InstAttCls.ca3."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
#: Doc comment for instance attribute InstAttCls.ia1
|
||||||
|
self.ia1 = 'd'
|
||||||
|
|
||||||
|
self.ia2 = 'e'
|
||||||
|
"""Docstring for instance attribute InstAttCls.ia2."""
|
||||||
|
|
||||||
|
|
||||||
|
class EnumCls(enum.Enum):
|
||||||
|
"""
|
||||||
|
this is enum class
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: doc for val1
|
||||||
|
val1 = 12
|
||||||
|
val2 = 23 #: doc for val2
|
||||||
|
val3 = 34
|
||||||
|
"""doc for val3"""
|
10
tests/roots/test-latex-numfig/conf.py
Normal file
10
tests/roots/test-latex-numfig/conf.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
latex_documents = [
|
||||||
|
('indexmanual', 'SphinxManual.tex', 'Test numfig manual',
|
||||||
|
'Sphinx', 'manual'),
|
||||||
|
('indexhowto', 'SphinxHowTo.tex', 'Test numfig howto',
|
||||||
|
'Sphinx', 'howto'),
|
||||||
|
]
|
9
tests/roots/test-latex-numfig/index.rst
Normal file
9
tests/roots/test-latex-numfig/index.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
=================
|
||||||
|
test-latex-numfig
|
||||||
|
=================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:numbered:
|
||||||
|
|
||||||
|
indexmanual
|
||||||
|
indexhowto
|
10
tests/roots/test-latex-numfig/indexhowto.rst
Normal file
10
tests/roots/test-latex-numfig/indexhowto.rst
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
=======================
|
||||||
|
test-latex-numfig-howto
|
||||||
|
=======================
|
||||||
|
|
||||||
|
This is a part
|
||||||
|
==============
|
||||||
|
|
||||||
|
This is a section
|
||||||
|
-----------------
|
||||||
|
|
13
tests/roots/test-latex-numfig/indexmanual.rst
Normal file
13
tests/roots/test-latex-numfig/indexmanual.rst
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
========================
|
||||||
|
test-latex-numfig-manual
|
||||||
|
========================
|
||||||
|
|
||||||
|
First part
|
||||||
|
==========
|
||||||
|
|
||||||
|
This is chapter
|
||||||
|
---------------
|
||||||
|
|
||||||
|
This is section
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
@ -5,7 +5,7 @@ Just testing a few autodoc possibilities...
|
|||||||
|
|
||||||
.. automodule:: util
|
.. automodule:: util
|
||||||
|
|
||||||
.. automodule:: test_autodoc
|
.. automodule:: autodoc_target
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. autofunction:: function
|
.. autofunction:: function
|
||||||
@ -34,7 +34,7 @@ Just testing a few autodoc possibilities...
|
|||||||
.. autoclass:: MarkupError
|
.. autoclass:: MarkupError
|
||||||
|
|
||||||
|
|
||||||
.. currentmodule:: test_autodoc
|
.. currentmodule:: autodoc_target
|
||||||
|
|
||||||
.. autoclass:: InstAttCls
|
.. autoclass:: InstAttCls
|
||||||
:members:
|
:members:
|
||||||
|
225
tests/roots/test-root/autodoc_target.py
Normal file
225
tests/roots/test-root/autodoc_target.py
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import enum
|
||||||
|
from six import StringIO, add_metaclass
|
||||||
|
from sphinx.ext.autodoc import add_documenter # NOQA
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Class']
|
||||||
|
|
||||||
|
#: documentation for the integer
|
||||||
|
integer = 1
|
||||||
|
|
||||||
|
|
||||||
|
def raises(exc, func, *args, **kwds):
|
||||||
|
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomEx(Exception):
|
||||||
|
"""My custom exception."""
|
||||||
|
|
||||||
|
def f(self):
|
||||||
|
"""Exception method."""
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDataDescriptor(object):
|
||||||
|
"""Descriptor class docstring."""
|
||||||
|
|
||||||
|
def __init__(self, doc):
|
||||||
|
self.__doc__ = doc
|
||||||
|
|
||||||
|
def __get__(self, obj, type=None):
|
||||||
|
if obj is None:
|
||||||
|
return self
|
||||||
|
return 42
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Function."""
|
||||||
|
return "The Answer"
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDataDescriptorMeta(type):
|
||||||
|
"""Descriptor metaclass docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
@add_metaclass(CustomDataDescriptorMeta)
|
||||||
|
class CustomDataDescriptor2(CustomDataDescriptor):
|
||||||
|
"""Descriptor class with custom metaclass docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
def _funky_classmethod(name, b, c, d, docstring=None):
|
||||||
|
"""Generates a classmethod for a class from a template by filling out
|
||||||
|
some arguments."""
|
||||||
|
def template(cls, a, b, c, d=4, e=5, f=6):
|
||||||
|
return a, b, c, d, e, f
|
||||||
|
from functools import partial
|
||||||
|
function = partial(template, b=b, c=c, d=d)
|
||||||
|
function.__name__ = name
|
||||||
|
function.__doc__ = docstring
|
||||||
|
return classmethod(function)
|
||||||
|
|
||||||
|
|
||||||
|
class Base(object):
|
||||||
|
def inheritedmeth(self):
|
||||||
|
"""Inherited function."""
|
||||||
|
|
||||||
|
|
||||||
|
class Derived(Base):
|
||||||
|
def inheritedmeth(self):
|
||||||
|
# no docstring here
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Class(Base):
|
||||||
|
"""Class to document."""
|
||||||
|
|
||||||
|
descr = CustomDataDescriptor("Descriptor instance docstring.")
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Function."""
|
||||||
|
|
||||||
|
def undocmeth(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def skipmeth(self):
|
||||||
|
"""Method that should be skipped."""
|
||||||
|
|
||||||
|
def excludemeth(self):
|
||||||
|
"""Method that should be excluded."""
|
||||||
|
|
||||||
|
# should not be documented
|
||||||
|
skipattr = 'foo'
|
||||||
|
|
||||||
|
#: should be documented -- süß
|
||||||
|
attr = 'bar'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop(self):
|
||||||
|
"""Property."""
|
||||||
|
|
||||||
|
docattr = 'baz'
|
||||||
|
"""should likewise be documented -- süß"""
|
||||||
|
|
||||||
|
udocattr = 'quux'
|
||||||
|
u"""should be documented as well - süß"""
|
||||||
|
|
||||||
|
# initialized to any class imported from another module
|
||||||
|
mdocattr = StringIO()
|
||||||
|
"""should be documented as well - süß"""
|
||||||
|
|
||||||
|
roger = _funky_classmethod("roger", 2, 3, 4)
|
||||||
|
|
||||||
|
moore = _funky_classmethod("moore", 9, 8, 7,
|
||||||
|
docstring="moore(a, e, f) -> happiness")
|
||||||
|
|
||||||
|
def __init__(self, arg):
|
||||||
|
self.inst_attr_inline = None #: an inline documented instance attr
|
||||||
|
#: a documented instance attribute
|
||||||
|
self.inst_attr_comment = None
|
||||||
|
self.inst_attr_string = None
|
||||||
|
"""a documented instance attribute"""
|
||||||
|
self._private_inst_attr = None #: a private instance attribute
|
||||||
|
|
||||||
|
def __special1__(self):
|
||||||
|
"""documented special method"""
|
||||||
|
|
||||||
|
def __special2__(self):
|
||||||
|
# undocumented special method
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomDict(dict):
|
||||||
|
"""Docstring."""
|
||||||
|
|
||||||
|
|
||||||
|
def function(foo, *args, **kwds):
|
||||||
|
"""
|
||||||
|
Return spam.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Outer(object):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
class Inner(object):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
def meth(self):
|
||||||
|
"""Foo"""
|
||||||
|
|
||||||
|
# should be documented as an alias
|
||||||
|
factory = dict
|
||||||
|
|
||||||
|
|
||||||
|
class DocstringSig(object):
|
||||||
|
def meth(self):
|
||||||
|
"""meth(FOO, BAR=1) -> BAZ
|
||||||
|
First line of docstring
|
||||||
|
|
||||||
|
rest of docstring
|
||||||
|
"""
|
||||||
|
|
||||||
|
def meth2(self):
|
||||||
|
"""First line, no signature
|
||||||
|
Second line followed by indentation::
|
||||||
|
|
||||||
|
indented line
|
||||||
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop1(self):
|
||||||
|
"""DocstringSig.prop1(self)
|
||||||
|
First line of docstring
|
||||||
|
"""
|
||||||
|
return 123
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prop2(self):
|
||||||
|
"""First line of docstring
|
||||||
|
Second line of docstring
|
||||||
|
"""
|
||||||
|
return 456
|
||||||
|
|
||||||
|
|
||||||
|
class StrRepr(str):
|
||||||
|
def __repr__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class AttCls(object):
|
||||||
|
a1 = StrRepr('hello\nworld')
|
||||||
|
a2 = None
|
||||||
|
|
||||||
|
|
||||||
|
class InstAttCls(object):
|
||||||
|
"""Class with documented class and instance attributes."""
|
||||||
|
|
||||||
|
#: Doc comment for class attribute InstAttCls.ca1.
|
||||||
|
#: It can have multiple lines.
|
||||||
|
ca1 = 'a'
|
||||||
|
|
||||||
|
ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
|
||||||
|
|
||||||
|
ca3 = 'c'
|
||||||
|
"""Docstring for class attribute InstAttCls.ca3."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
#: Doc comment for instance attribute InstAttCls.ia1
|
||||||
|
self.ia1 = 'd'
|
||||||
|
|
||||||
|
self.ia2 = 'e'
|
||||||
|
"""Docstring for instance attribute InstAttCls.ia2."""
|
||||||
|
|
||||||
|
|
||||||
|
class EnumCls(enum.Enum):
|
||||||
|
"""
|
||||||
|
this is enum class
|
||||||
|
"""
|
||||||
|
|
||||||
|
#: doc for val1
|
||||||
|
val1 = 12
|
||||||
|
val2 = 23 #: doc for val2
|
||||||
|
val3 = 34
|
||||||
|
"""doc for val3"""
|
@ -10,13 +10,12 @@
|
|||||||
:license: BSD, see LICENSE for details.
|
:license: BSD, see LICENSE for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
from six import PY3
|
from six import PY3
|
||||||
|
|
||||||
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import enum
|
|
||||||
from six import StringIO, add_metaclass
|
|
||||||
from docutils.statemachine import ViewList
|
from docutils.statemachine import ViewList
|
||||||
|
|
||||||
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
|
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
|
||||||
@ -27,18 +26,23 @@ app = None
|
|||||||
|
|
||||||
@pytest.fixture(scope='module', autouse=True)
|
@pytest.fixture(scope='module', autouse=True)
|
||||||
def setup_module(rootdir, sphinx_test_tempdir):
|
def setup_module(rootdir, sphinx_test_tempdir):
|
||||||
global app
|
try:
|
||||||
srcdir = sphinx_test_tempdir / 'autodoc-root'
|
global app
|
||||||
if not srcdir.exists():
|
srcdir = sphinx_test_tempdir / 'autodoc-root'
|
||||||
(rootdir/'test-root').copytree(srcdir)
|
if not srcdir.exists():
|
||||||
app = SphinxTestApp(srcdir=srcdir)
|
(rootdir / 'test-root').copytree(srcdir)
|
||||||
app.builder.env.app = app
|
testroot = rootdir / 'test-ext-autodoc'
|
||||||
app.builder.env.temp_data['docname'] = 'dummy'
|
sys.path.append(testroot)
|
||||||
app.connect('autodoc-process-docstring', process_docstring)
|
app = SphinxTestApp(srcdir=srcdir)
|
||||||
app.connect('autodoc-process-signature', process_signature)
|
app.builder.env.app = app
|
||||||
app.connect('autodoc-skip-member', skip_member)
|
app.builder.env.temp_data['docname'] = 'dummy'
|
||||||
yield
|
app.connect('autodoc-process-docstring', process_docstring)
|
||||||
app.cleanup()
|
app.connect('autodoc-process-signature', process_signature)
|
||||||
|
app.connect('autodoc-skip-member', skip_member)
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
app.cleanup()
|
||||||
|
sys.path.remove(testroot)
|
||||||
|
|
||||||
|
|
||||||
directive = options = None
|
directive = options = None
|
||||||
@ -432,6 +436,8 @@ def test_get_doc():
|
|||||||
directive.env.config.autoclass_content = 'both'
|
directive.env.config.autoclass_content = 'both'
|
||||||
assert getdocl('class', I) == ['Class docstring', '', 'New docstring']
|
assert getdocl('class', I) == ['Class docstring', '', 'New docstring']
|
||||||
|
|
||||||
|
from target import Base, Derived
|
||||||
|
|
||||||
# NOTE: inspect.getdoc seems not to work with locally defined classes
|
# NOTE: inspect.getdoc seems not to work with locally defined classes
|
||||||
directive.env.config.autodoc_inherit_docstrings = False
|
directive.env.config.autodoc_inherit_docstrings = False
|
||||||
assert getdocl('method', Base.inheritedmeth) == ['Inherited function.']
|
assert getdocl('method', Base.inheritedmeth) == ['Inherited function.']
|
||||||
@ -509,24 +515,24 @@ def test_docstring_property_processing():
|
|||||||
|
|
||||||
directive.env.config.autodoc_docstring_signature = False
|
directive.env.config.autodoc_docstring_signature = False
|
||||||
results, docstrings = \
|
results, docstrings = \
|
||||||
genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
|
genarate_docstring('attribute', 'target.DocstringSig.prop1')
|
||||||
assert '.. py:attribute:: DocstringSig.prop1' in results
|
assert '.. py:attribute:: DocstringSig.prop1' in results
|
||||||
assert 'First line of docstring' in docstrings
|
assert 'First line of docstring' in docstrings
|
||||||
assert 'DocstringSig.prop1(self)' in docstrings
|
assert 'DocstringSig.prop1(self)' in docstrings
|
||||||
results, docstrings = \
|
results, docstrings = \
|
||||||
genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
|
genarate_docstring('attribute', 'target.DocstringSig.prop2')
|
||||||
assert '.. py:attribute:: DocstringSig.prop2' in results
|
assert '.. py:attribute:: DocstringSig.prop2' in results
|
||||||
assert 'First line of docstring' in docstrings
|
assert 'First line of docstring' in docstrings
|
||||||
assert 'Second line of docstring' in docstrings
|
assert 'Second line of docstring' in docstrings
|
||||||
|
|
||||||
directive.env.config.autodoc_docstring_signature = True
|
directive.env.config.autodoc_docstring_signature = True
|
||||||
results, docstrings = \
|
results, docstrings = \
|
||||||
genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
|
genarate_docstring('attribute', 'target.DocstringSig.prop1')
|
||||||
assert '.. py:attribute:: DocstringSig.prop1' in results
|
assert '.. py:attribute:: DocstringSig.prop1' in results
|
||||||
assert 'First line of docstring' in docstrings
|
assert 'First line of docstring' in docstrings
|
||||||
assert 'DocstringSig.prop1(self)' not in docstrings
|
assert 'DocstringSig.prop1(self)' not in docstrings
|
||||||
results, docstrings = \
|
results, docstrings = \
|
||||||
genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
|
genarate_docstring('attribute', 'target.DocstringSig.prop2')
|
||||||
assert '.. py:attribute:: DocstringSig.prop2' in results
|
assert '.. py:attribute:: DocstringSig.prop2' in results
|
||||||
assert 'First line of docstring' in docstrings
|
assert 'First line of docstring' in docstrings
|
||||||
assert 'Second line of docstring' in docstrings
|
assert 'Second line of docstring' in docstrings
|
||||||
@ -557,11 +563,13 @@ def test_new_documenter():
|
|||||||
del directive.result[:]
|
del directive.result[:]
|
||||||
|
|
||||||
options.members = ['integer']
|
options.members = ['integer']
|
||||||
assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc')
|
assert_result_contains('.. py:data:: integer', 'module', 'target')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('setup_test')
|
@pytest.mark.usefixtures('setup_test')
|
||||||
def test_attrgetter_using():
|
def test_attrgetter_using():
|
||||||
|
from target import Class
|
||||||
|
|
||||||
def assert_getter_works(objtype, name, obj, attrs=[], **kw):
|
def assert_getter_works(objtype, name, obj, attrs=[], **kw):
|
||||||
getattr_spy = []
|
getattr_spy = []
|
||||||
|
|
||||||
@ -586,10 +594,10 @@ def test_attrgetter_using():
|
|||||||
|
|
||||||
options.members = ALL
|
options.members = ALL
|
||||||
options.inherited_members = False
|
options.inherited_members = False
|
||||||
assert_getter_works('class', 'test_autodoc.Class', Class, ['meth'])
|
assert_getter_works('class', 'target.Class', Class, ['meth'])
|
||||||
|
|
||||||
options.inherited_members = True
|
options.inherited_members = True
|
||||||
assert_getter_works('class', 'test_autodoc.Class', Class, ['meth', 'inheritedmeth'])
|
assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth'])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('setup_test')
|
@pytest.mark.usefixtures('setup_test')
|
||||||
@ -656,11 +664,11 @@ def test_generate():
|
|||||||
assert_warns("failed to import function 'foobar' from module 'util'",
|
assert_warns("failed to import function 'foobar' from module 'util'",
|
||||||
'function', 'util.foobar', more_content=None)
|
'function', 'util.foobar', more_content=None)
|
||||||
# method missing
|
# method missing
|
||||||
assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc';",
|
assert_warns("failed to import method 'Class.foobar' from module 'target';",
|
||||||
'method', 'test_autodoc.Class.foobar', more_content=None)
|
'method', 'target.Class.foobar', more_content=None)
|
||||||
|
|
||||||
# test auto and given content mixing
|
# test auto and given content mixing
|
||||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
directive.env.ref_context['py:module'] = 'target'
|
||||||
assert_result_contains(' Function.', 'method', 'Class.meth')
|
assert_result_contains(' Function.', 'method', 'Class.meth')
|
||||||
add_content = ViewList()
|
add_content = ViewList()
|
||||||
add_content.append('Content.', '', 0)
|
add_content.append('Content.', '', 0)
|
||||||
@ -675,63 +683,63 @@ def test_generate():
|
|||||||
assert len(directive.result) == 0
|
assert len(directive.result) == 0
|
||||||
|
|
||||||
# assert that exceptions can be documented
|
# assert that exceptions can be documented
|
||||||
assert_works('exception', 'test_autodoc.CustomEx', all_members=True)
|
assert_works('exception', 'target.CustomEx', all_members=True)
|
||||||
assert_works('exception', 'test_autodoc.CustomEx')
|
assert_works('exception', 'target.CustomEx')
|
||||||
|
|
||||||
# test diverse inclusion settings for members
|
# test diverse inclusion settings for members
|
||||||
should = [('class', 'test_autodoc.Class')]
|
should = [('class', 'target.Class')]
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
should.extend([('method', 'test_autodoc.Class.meth')])
|
should.extend([('method', 'target.Class.meth')])
|
||||||
options.members = ['meth']
|
options.members = ['meth']
|
||||||
options.exclude_members = set(['excludemeth'])
|
options.exclude_members = set(['excludemeth'])
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
should.extend([('attribute', 'test_autodoc.Class.prop'),
|
should.extend([('attribute', 'target.Class.prop'),
|
||||||
('attribute', 'test_autodoc.Class.descr'),
|
('attribute', 'target.Class.descr'),
|
||||||
('attribute', 'test_autodoc.Class.attr'),
|
('attribute', 'target.Class.attr'),
|
||||||
('attribute', 'test_autodoc.Class.docattr'),
|
('attribute', 'target.Class.docattr'),
|
||||||
('attribute', 'test_autodoc.Class.udocattr'),
|
('attribute', 'target.Class.udocattr'),
|
||||||
('attribute', 'test_autodoc.Class.mdocattr'),
|
('attribute', 'target.Class.mdocattr'),
|
||||||
('attribute', 'test_autodoc.Class.inst_attr_comment'),
|
('attribute', 'target.Class.inst_attr_comment'),
|
||||||
('attribute', 'test_autodoc.Class.inst_attr_inline'),
|
('attribute', 'target.Class.inst_attr_inline'),
|
||||||
('attribute', 'test_autodoc.Class.inst_attr_string'),
|
('attribute', 'target.Class.inst_attr_string'),
|
||||||
('method', 'test_autodoc.Class.moore'),
|
('method', 'target.Class.moore'),
|
||||||
])
|
])
|
||||||
options.members = ALL
|
options.members = ALL
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
options.undoc_members = True
|
options.undoc_members = True
|
||||||
should.extend((('attribute', 'test_autodoc.Class.skipattr'),
|
should.extend((('attribute', 'target.Class.skipattr'),
|
||||||
('method', 'test_autodoc.Class.undocmeth'),
|
('method', 'target.Class.undocmeth'),
|
||||||
('method', 'test_autodoc.Class.roger')))
|
('method', 'target.Class.roger')))
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
options.inherited_members = True
|
options.inherited_members = True
|
||||||
should.append(('method', 'test_autodoc.Class.inheritedmeth'))
|
should.append(('method', 'target.Class.inheritedmeth'))
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
|
|
||||||
# test special members
|
# test special members
|
||||||
options.special_members = ['__special1__']
|
options.special_members = ['__special1__']
|
||||||
should.append(('method', 'test_autodoc.Class.__special1__'))
|
should.append(('method', 'target.Class.__special1__'))
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
options.special_members = ALL
|
options.special_members = ALL
|
||||||
should.append(('method', 'test_autodoc.Class.__special2__'))
|
should.append(('method', 'target.Class.__special2__'))
|
||||||
assert_processes(should, 'class', 'Class')
|
assert_processes(should, 'class', 'Class')
|
||||||
options.special_members = False
|
options.special_members = False
|
||||||
|
|
||||||
options.members = []
|
options.members = []
|
||||||
# test module flags
|
# test module flags
|
||||||
assert_result_contains('.. py:module:: test_autodoc',
|
assert_result_contains('.. py:module:: target',
|
||||||
'module', 'test_autodoc')
|
'module', 'target')
|
||||||
options.synopsis = 'Synopsis'
|
options.synopsis = 'Synopsis'
|
||||||
assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc')
|
assert_result_contains(' :synopsis: Synopsis', 'module', 'target')
|
||||||
options.deprecated = True
|
options.deprecated = True
|
||||||
assert_result_contains(' :deprecated:', 'module', 'test_autodoc')
|
assert_result_contains(' :deprecated:', 'module', 'target')
|
||||||
options.platform = 'Platform'
|
options.platform = 'Platform'
|
||||||
assert_result_contains(' :platform: Platform', 'module', 'test_autodoc')
|
assert_result_contains(' :platform: Platform', 'module', 'target')
|
||||||
# test if __all__ is respected for modules
|
# test if __all__ is respected for modules
|
||||||
options.members = ALL
|
options.members = ALL
|
||||||
assert_result_contains('.. py:class:: Class(arg)', 'module', 'test_autodoc')
|
assert_result_contains('.. py:class:: Class(arg)', 'module', 'target')
|
||||||
try:
|
try:
|
||||||
assert_result_contains('.. py:exception:: CustomEx',
|
assert_result_contains('.. py:exception:: CustomEx',
|
||||||
'module', 'test_autodoc')
|
'module', 'target')
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -746,7 +754,7 @@ def test_generate():
|
|||||||
# test noindex flag
|
# test noindex flag
|
||||||
options.members = []
|
options.members = []
|
||||||
options.noindex = True
|
options.noindex = True
|
||||||
assert_result_contains(' :noindex:', 'module', 'test_autodoc')
|
assert_result_contains(' :noindex:', 'module', 'target')
|
||||||
assert_result_contains(' :noindex:', 'class', 'Base')
|
assert_result_contains(' :noindex:', 'class', 'Base')
|
||||||
|
|
||||||
# okay, now let's get serious about mixing Python and C signature stuff
|
# okay, now let's get serious about mixing Python and C signature stuff
|
||||||
@ -754,14 +762,14 @@ def test_generate():
|
|||||||
all_members=True)
|
all_members=True)
|
||||||
|
|
||||||
# test inner class handling
|
# test inner class handling
|
||||||
assert_processes([('class', 'test_autodoc.Outer'),
|
assert_processes([('class', 'target.Outer'),
|
||||||
('class', 'test_autodoc.Outer.Inner'),
|
('class', 'target.Outer.Inner'),
|
||||||
('method', 'test_autodoc.Outer.Inner.meth')],
|
('method', 'target.Outer.Inner.meth')],
|
||||||
'class', 'Outer', all_members=True)
|
'class', 'Outer', all_members=True)
|
||||||
|
|
||||||
# test descriptor docstrings
|
# test descriptor docstrings
|
||||||
assert_result_contains(' Descriptor instance docstring.',
|
assert_result_contains(' Descriptor instance docstring.',
|
||||||
'attribute', 'test_autodoc.Class.descr')
|
'attribute', 'target.Class.descr')
|
||||||
|
|
||||||
# test generation for C modules (which have no source file)
|
# test generation for C modules (which have no source file)
|
||||||
directive.env.ref_context['py:module'] = 'time'
|
directive.env.ref_context['py:module'] = 'time'
|
||||||
@ -769,7 +777,7 @@ def test_generate():
|
|||||||
assert_processes([('function', 'time.asctime')], 'function', 'asctime')
|
assert_processes([('function', 'time.asctime')], 'function', 'asctime')
|
||||||
|
|
||||||
# test autodoc_member_order == 'source'
|
# test autodoc_member_order == 'source'
|
||||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
directive.env.ref_context['py:module'] = 'target'
|
||||||
options.private_members = True
|
options.private_members = True
|
||||||
if PY3:
|
if PY3:
|
||||||
roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)'
|
roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)'
|
||||||
@ -795,7 +803,7 @@ def test_generate():
|
|||||||
del directive.env.ref_context['py:module']
|
del directive.env.ref_context['py:module']
|
||||||
|
|
||||||
# test attribute initialized to class instance from other module
|
# test attribute initialized to class instance from other module
|
||||||
directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class'
|
directive.env.temp_data['autodoc:class'] = 'target.Class'
|
||||||
assert_result_contains(u' should be documented as well - s\xfc\xdf',
|
assert_result_contains(u' should be documented as well - s\xfc\xdf',
|
||||||
'attribute', 'mdocattr')
|
'attribute', 'mdocattr')
|
||||||
del directive.env.temp_data['autodoc:class']
|
del directive.env.temp_data['autodoc:class']
|
||||||
@ -803,25 +811,25 @@ def test_generate():
|
|||||||
# test autodoc_docstring_signature
|
# test autodoc_docstring_signature
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
'.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method',
|
'.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method',
|
||||||
'test_autodoc.DocstringSig.meth')
|
'target.DocstringSig.meth')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth')
|
' rest of docstring', 'method', 'target.DocstringSig.meth')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
'.. py:method:: DocstringSig.meth2()', 'method',
|
'.. py:method:: DocstringSig.meth2()', 'method',
|
||||||
'test_autodoc.DocstringSig.meth2')
|
'target.DocstringSig.meth2')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
' indented line', 'method',
|
' indented line', 'method',
|
||||||
'test_autodoc.DocstringSig.meth2')
|
'target.DocstringSig.meth2')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
'.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method',
|
'.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method',
|
||||||
'test_autodoc.Class.moore')
|
'target.Class.moore')
|
||||||
|
|
||||||
# test new attribute documenter behavior
|
# test new attribute documenter behavior
|
||||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
directive.env.ref_context['py:module'] = 'target'
|
||||||
options.undoc_members = True
|
options.undoc_members = True
|
||||||
assert_processes([('class', 'test_autodoc.AttCls'),
|
assert_processes([('class', 'target.AttCls'),
|
||||||
('attribute', 'test_autodoc.AttCls.a1'),
|
('attribute', 'target.AttCls.a1'),
|
||||||
('attribute', 'test_autodoc.AttCls.a2'),
|
('attribute', 'target.AttCls.a2'),
|
||||||
], 'class', 'AttCls')
|
], 'class', 'AttCls')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
' :annotation: = hello world', 'attribute', 'AttCls.a1')
|
' :annotation: = hello world', 'attribute', 'AttCls.a1')
|
||||||
@ -831,40 +839,40 @@ def test_generate():
|
|||||||
# test explicit members with instance attributes
|
# test explicit members with instance attributes
|
||||||
del directive.env.temp_data['autodoc:class']
|
del directive.env.temp_data['autodoc:class']
|
||||||
del directive.env.temp_data['autodoc:module']
|
del directive.env.temp_data['autodoc:module']
|
||||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
directive.env.ref_context['py:module'] = 'target'
|
||||||
options.inherited_members = False
|
options.inherited_members = False
|
||||||
options.undoc_members = False
|
options.undoc_members = False
|
||||||
options.members = ALL
|
options.members = ALL
|
||||||
assert_processes([
|
assert_processes([
|
||||||
('class', 'test_autodoc.InstAttCls'),
|
('class', 'target.InstAttCls'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ca1'),
|
('attribute', 'target.InstAttCls.ca1'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ca2'),
|
('attribute', 'target.InstAttCls.ca2'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ca3'),
|
('attribute', 'target.InstAttCls.ca3'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ia1'),
|
('attribute', 'target.InstAttCls.ia1'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ia2'),
|
('attribute', 'target.InstAttCls.ia2'),
|
||||||
], 'class', 'InstAttCls')
|
], 'class', 'InstAttCls')
|
||||||
del directive.env.temp_data['autodoc:class']
|
del directive.env.temp_data['autodoc:class']
|
||||||
del directive.env.temp_data['autodoc:module']
|
del directive.env.temp_data['autodoc:module']
|
||||||
options.members = ['ca1', 'ia1']
|
options.members = ['ca1', 'ia1']
|
||||||
assert_processes([
|
assert_processes([
|
||||||
('class', 'test_autodoc.InstAttCls'),
|
('class', 'target.InstAttCls'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ca1'),
|
('attribute', 'target.InstAttCls.ca1'),
|
||||||
('attribute', 'test_autodoc.InstAttCls.ia1'),
|
('attribute', 'target.InstAttCls.ia1'),
|
||||||
], 'class', 'InstAttCls')
|
], 'class', 'InstAttCls')
|
||||||
del directive.env.temp_data['autodoc:class']
|
del directive.env.temp_data['autodoc:class']
|
||||||
del directive.env.temp_data['autodoc:module']
|
del directive.env.temp_data['autodoc:module']
|
||||||
del directive.env.ref_context['py:module']
|
del directive.env.ref_context['py:module']
|
||||||
|
|
||||||
# test members with enum attributes
|
# test members with enum attributes
|
||||||
directive.env.ref_context['py:module'] = 'test_autodoc'
|
directive.env.ref_context['py:module'] = 'target'
|
||||||
options.inherited_members = False
|
options.inherited_members = False
|
||||||
options.undoc_members = False
|
options.undoc_members = False
|
||||||
options.members = ALL
|
options.members = ALL
|
||||||
assert_processes([
|
assert_processes([
|
||||||
('class', 'test_autodoc.EnumCls'),
|
('class', 'target.EnumCls'),
|
||||||
('attribute', 'test_autodoc.EnumCls.val1'),
|
('attribute', 'target.EnumCls.val1'),
|
||||||
('attribute', 'test_autodoc.EnumCls.val2'),
|
('attribute', 'target.EnumCls.val2'),
|
||||||
('attribute', 'test_autodoc.EnumCls.val3'),
|
('attribute', 'target.EnumCls.val3'),
|
||||||
], 'class', 'EnumCls')
|
], 'class', 'EnumCls')
|
||||||
assert_result_contains(
|
assert_result_contains(
|
||||||
' :annotation: = 12', 'attribute', 'EnumCls.val1')
|
' :annotation: = 12', 'attribute', 'EnumCls.val1')
|
||||||
@ -878,11 +886,11 @@ def test_generate():
|
|||||||
# test descriptor class documentation
|
# test descriptor class documentation
|
||||||
options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2']
|
options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2']
|
||||||
assert_result_contains('.. py:class:: CustomDataDescriptor(doc)',
|
assert_result_contains('.. py:class:: CustomDataDescriptor(doc)',
|
||||||
'module', 'test_autodoc')
|
'module', 'target')
|
||||||
assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()',
|
assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()',
|
||||||
'module', 'test_autodoc')
|
'module', 'target')
|
||||||
assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)',
|
assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)',
|
||||||
'module', 'test_autodoc')
|
'module', 'target')
|
||||||
|
|
||||||
# test mocked module imports
|
# test mocked module imports
|
||||||
options.members = ['TestAutodoc']
|
options.members = ['TestAutodoc']
|
||||||
@ -894,224 +902,3 @@ def test_generate():
|
|||||||
options.members = ['decoratedFunction']
|
options.members = ['decoratedFunction']
|
||||||
assert_result_contains('.. py:function:: decoratedFunction()',
|
assert_result_contains('.. py:function:: decoratedFunction()',
|
||||||
'module', 'autodoc_missing_imports')
|
'module', 'autodoc_missing_imports')
|
||||||
|
|
||||||
|
|
||||||
# --- generate fodder ------------
|
|
||||||
__all__ = ['Class']
|
|
||||||
|
|
||||||
#: documentation for the integer
|
|
||||||
integer = 1
|
|
||||||
|
|
||||||
|
|
||||||
def raises(exc, func, *args, **kwds):
|
|
||||||
"""Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CustomEx(Exception):
|
|
||||||
"""My custom exception."""
|
|
||||||
|
|
||||||
def f(self):
|
|
||||||
"""Exception method."""
|
|
||||||
|
|
||||||
|
|
||||||
class CustomDataDescriptor(object):
|
|
||||||
"""Descriptor class docstring."""
|
|
||||||
|
|
||||||
def __init__(self, doc):
|
|
||||||
self.__doc__ = doc
|
|
||||||
|
|
||||||
def __get__(self, obj, type=None):
|
|
||||||
if obj is None:
|
|
||||||
return self
|
|
||||||
return 42
|
|
||||||
|
|
||||||
def meth(self):
|
|
||||||
"""Function."""
|
|
||||||
return "The Answer"
|
|
||||||
|
|
||||||
|
|
||||||
class CustomDataDescriptorMeta(type):
|
|
||||||
"""Descriptor metaclass docstring."""
|
|
||||||
|
|
||||||
|
|
||||||
@add_metaclass(CustomDataDescriptorMeta)
|
|
||||||
class CustomDataDescriptor2(CustomDataDescriptor):
|
|
||||||
"""Descriptor class with custom metaclass docstring."""
|
|
||||||
|
|
||||||
|
|
||||||
def _funky_classmethod(name, b, c, d, docstring=None):
|
|
||||||
"""Generates a classmethod for a class from a template by filling out
|
|
||||||
some arguments."""
|
|
||||||
def template(cls, a, b, c, d=4, e=5, f=6):
|
|
||||||
return a, b, c, d, e, f
|
|
||||||
from functools import partial
|
|
||||||
function = partial(template, b=b, c=c, d=d)
|
|
||||||
function.__name__ = name
|
|
||||||
function.__doc__ = docstring
|
|
||||||
return classmethod(function)
|
|
||||||
|
|
||||||
|
|
||||||
class Base(object):
|
|
||||||
def inheritedmeth(self):
|
|
||||||
"""Inherited function."""
|
|
||||||
|
|
||||||
|
|
||||||
class Derived(Base):
|
|
||||||
def inheritedmeth(self):
|
|
||||||
# no docstring here
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Class(Base):
|
|
||||||
"""Class to document."""
|
|
||||||
|
|
||||||
descr = CustomDataDescriptor("Descriptor instance docstring.")
|
|
||||||
|
|
||||||
def meth(self):
|
|
||||||
"""Function."""
|
|
||||||
|
|
||||||
def undocmeth(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def skipmeth(self):
|
|
||||||
"""Method that should be skipped."""
|
|
||||||
|
|
||||||
def excludemeth(self):
|
|
||||||
"""Method that should be excluded."""
|
|
||||||
|
|
||||||
# should not be documented
|
|
||||||
skipattr = 'foo'
|
|
||||||
|
|
||||||
#: should be documented -- süß
|
|
||||||
attr = 'bar'
|
|
||||||
|
|
||||||
@property
|
|
||||||
def prop(self):
|
|
||||||
"""Property."""
|
|
||||||
|
|
||||||
docattr = 'baz'
|
|
||||||
"""should likewise be documented -- süß"""
|
|
||||||
|
|
||||||
udocattr = 'quux'
|
|
||||||
u"""should be documented as well - süß"""
|
|
||||||
|
|
||||||
# initialized to any class imported from another module
|
|
||||||
mdocattr = StringIO()
|
|
||||||
"""should be documented as well - süß"""
|
|
||||||
|
|
||||||
roger = _funky_classmethod("roger", 2, 3, 4)
|
|
||||||
|
|
||||||
moore = _funky_classmethod("moore", 9, 8, 7,
|
|
||||||
docstring="moore(a, e, f) -> happiness")
|
|
||||||
|
|
||||||
def __init__(self, arg):
|
|
||||||
self.inst_attr_inline = None #: an inline documented instance attr
|
|
||||||
#: a documented instance attribute
|
|
||||||
self.inst_attr_comment = None
|
|
||||||
self.inst_attr_string = None
|
|
||||||
"""a documented instance attribute"""
|
|
||||||
self._private_inst_attr = None #: a private instance attribute
|
|
||||||
|
|
||||||
def __special1__(self):
|
|
||||||
"""documented special method"""
|
|
||||||
|
|
||||||
def __special2__(self):
|
|
||||||
# undocumented special method
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class CustomDict(dict):
|
|
||||||
"""Docstring."""
|
|
||||||
|
|
||||||
|
|
||||||
def function(foo, *args, **kwds):
|
|
||||||
"""
|
|
||||||
Return spam.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Outer(object):
|
|
||||||
"""Foo"""
|
|
||||||
|
|
||||||
class Inner(object):
|
|
||||||
"""Foo"""
|
|
||||||
|
|
||||||
def meth(self):
|
|
||||||
"""Foo"""
|
|
||||||
|
|
||||||
# should be documented as an alias
|
|
||||||
factory = dict
|
|
||||||
|
|
||||||
|
|
||||||
class DocstringSig(object):
|
|
||||||
def meth(self):
|
|
||||||
"""meth(FOO, BAR=1) -> BAZ
|
|
||||||
First line of docstring
|
|
||||||
|
|
||||||
rest of docstring
|
|
||||||
"""
|
|
||||||
|
|
||||||
def meth2(self):
|
|
||||||
"""First line, no signature
|
|
||||||
Second line followed by indentation::
|
|
||||||
|
|
||||||
indented line
|
|
||||||
"""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def prop1(self):
|
|
||||||
"""DocstringSig.prop1(self)
|
|
||||||
First line of docstring
|
|
||||||
"""
|
|
||||||
return 123
|
|
||||||
|
|
||||||
@property
|
|
||||||
def prop2(self):
|
|
||||||
"""First line of docstring
|
|
||||||
Second line of docstring
|
|
||||||
"""
|
|
||||||
return 456
|
|
||||||
|
|
||||||
|
|
||||||
class StrRepr(str):
|
|
||||||
def __repr__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
class AttCls(object):
|
|
||||||
a1 = StrRepr('hello\nworld')
|
|
||||||
a2 = None
|
|
||||||
|
|
||||||
|
|
||||||
class InstAttCls(object):
|
|
||||||
"""Class with documented class and instance attributes."""
|
|
||||||
|
|
||||||
#: Doc comment for class attribute InstAttCls.ca1.
|
|
||||||
#: It can have multiple lines.
|
|
||||||
ca1 = 'a'
|
|
||||||
|
|
||||||
ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
|
|
||||||
|
|
||||||
ca3 = 'c'
|
|
||||||
"""Docstring for class attribute InstAttCls.ca3."""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
#: Doc comment for instance attribute InstAttCls.ia1
|
|
||||||
self.ia1 = 'd'
|
|
||||||
|
|
||||||
self.ia2 = 'e'
|
|
||||||
"""Docstring for instance attribute InstAttCls.ia2."""
|
|
||||||
|
|
||||||
|
|
||||||
class EnumCls(enum.Enum):
|
|
||||||
"""
|
|
||||||
this is enum class
|
|
||||||
"""
|
|
||||||
|
|
||||||
#: doc for val1
|
|
||||||
val1 = 12
|
|
||||||
val2 = 23 #: doc for val2
|
|
||||||
val3 = 34
|
|
||||||
"""doc for val3"""
|
|
||||||
|
@ -182,8 +182,8 @@ def test_html_warnings(app, warning):
|
|||||||
r'-| |-'),
|
r'-| |-'),
|
||||||
],
|
],
|
||||||
'autodoc.html': [
|
'autodoc.html': [
|
||||||
(".//dt[@id='test_autodoc.Class']", ''),
|
(".//dt[@id='autodoc_target.Class']", ''),
|
||||||
(".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'),
|
(".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'),
|
||||||
(".//dd/p", r'Return spam\.'),
|
(".//dd/p", r'Return spam\.'),
|
||||||
],
|
],
|
||||||
'extapi.html': [
|
'extapi.html': [
|
||||||
|
@ -90,8 +90,8 @@ def cached_etree_parse():
|
|||||||
r'-| |-'),
|
r'-| |-'),
|
||||||
],
|
],
|
||||||
'autodoc.html': [
|
'autodoc.html': [
|
||||||
(".//dt[@id='test_autodoc.Class']", ''),
|
(".//dt[@id='autodoc_target.Class']", ''),
|
||||||
(".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'),
|
(".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'),
|
||||||
(".//dd/p", r'Return spam\.'),
|
(".//dd/p", r'Return spam\.'),
|
||||||
],
|
],
|
||||||
'extapi.html': [
|
'extapi.html': [
|
||||||
|
@ -335,6 +335,43 @@ def test_numref_with_language_ja(app, status, warning):
|
|||||||
'\\nameref{\\detokenize{foo:foo}}}') in result
|
'\\nameref{\\detokenize{foo:foo}}}') in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx('latex', testroot='latex-numfig')
|
||||||
|
def test_latex_obey_numfig_is_false(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage{sphinx}' in result
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage{sphinx}' in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(
|
||||||
|
'latex', testroot='latex-numfig',
|
||||||
|
confoverrides={'numfig': True, 'numfig_secnum_depth': 0})
|
||||||
|
def test_latex_obey_numfig_secnum_depth_is_zero(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage[,nonumfigreset]{sphinx}' in result
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage[,nonumfigreset]{sphinx}' in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(
|
||||||
|
'latex', testroot='latex-numfig',
|
||||||
|
confoverrides={'numfig': True, 'numfig_secnum_depth': 2})
|
||||||
|
def test_latex_obey_numfig_secnum_depth_is_two(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage[,numfigreset=2]{sphinx}' in result
|
||||||
|
|
||||||
|
result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
|
||||||
|
assert '\\usepackage[,numfigreset=3]{sphinx}' in result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('latex')
|
@pytest.mark.sphinx('latex')
|
||||||
def test_latex_add_latex_package(app, status, warning):
|
def test_latex_add_latex_package(app, status, warning):
|
||||||
app.add_latex_package('foo')
|
app.add_latex_package('foo')
|
||||||
@ -712,20 +749,16 @@ def test_latex_logo_if_not_found(app, status, warning):
|
|||||||
assert isinstance(exc, SphinxError)
|
assert isinstance(exc, SphinxError)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx('latex', testroot='toctree-maxdepth',
|
@pytest.mark.sphinx('latex', testroot='toctree-maxdepth')
|
||||||
confoverrides={'latex_documents': [
|
|
||||||
('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
|
||||||
'Georg Brandl', 'manual'),
|
|
||||||
]})
|
|
||||||
def test_toctree_maxdepth_manual(app, status, warning):
|
def test_toctree_maxdepth_manual(app, status, warning):
|
||||||
app.builder.build_all()
|
app.builder.build_all()
|
||||||
result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
|
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||||
print(result)
|
print(result)
|
||||||
print(status.getvalue())
|
print(status.getvalue())
|
||||||
print(warning.getvalue())
|
print(warning.getvalue())
|
||||||
assert '\\setcounter{tocdepth}{1}' in result
|
assert '\\setcounter{tocdepth}{1}' in result
|
||||||
assert '\\setcounter{secnumdepth}' not in result
|
assert '\\setcounter{secnumdepth}' not in result
|
||||||
|
assert '\\chapter{Foo}' in result
|
||||||
|
|
||||||
@pytest.mark.sphinx(
|
@pytest.mark.sphinx(
|
||||||
'latex', testroot='toctree-maxdepth',
|
'latex', testroot='toctree-maxdepth',
|
||||||
@ -741,7 +774,7 @@ def test_toctree_maxdepth_howto(app, status, warning):
|
|||||||
print(warning.getvalue())
|
print(warning.getvalue())
|
||||||
assert '\\setcounter{tocdepth}{2}' in result
|
assert '\\setcounter{tocdepth}{2}' in result
|
||||||
assert '\\setcounter{secnumdepth}' not in result
|
assert '\\setcounter{secnumdepth}' not in result
|
||||||
|
assert '\\section{Foo}' in result
|
||||||
|
|
||||||
@pytest.mark.sphinx(
|
@pytest.mark.sphinx(
|
||||||
'latex', testroot='toctree-maxdepth',
|
'latex', testroot='toctree-maxdepth',
|
||||||
@ -754,7 +787,7 @@ def test_toctree_not_found(app, status, warning):
|
|||||||
print(warning.getvalue())
|
print(warning.getvalue())
|
||||||
assert '\\setcounter{tocdepth}' not in result
|
assert '\\setcounter{tocdepth}' not in result
|
||||||
assert '\\setcounter{secnumdepth}' not in result
|
assert '\\setcounter{secnumdepth}' not in result
|
||||||
|
assert '\\chapter{Foo A}' in result
|
||||||
|
|
||||||
@pytest.mark.sphinx(
|
@pytest.mark.sphinx(
|
||||||
'latex', testroot='toctree-maxdepth',
|
'latex', testroot='toctree-maxdepth',
|
||||||
@ -804,6 +837,26 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning):
|
|||||||
print(status.getvalue())
|
print(status.getvalue())
|
||||||
print(warning.getvalue())
|
print(warning.getvalue())
|
||||||
assert '\\part{Foo}' in result
|
assert '\\part{Foo}' in result
|
||||||
|
assert '\\chapter{Foo A}' in result
|
||||||
|
assert '\\chapter{Foo B}' in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(
|
||||||
|
'latex', testroot='toctree-maxdepth',
|
||||||
|
confoverrides={'latex_toplevel_sectioning': 'part',
|
||||||
|
'latex_documents': [
|
||||||
|
('index', 'Python.tex', 'Sphinx Tests Documentation',
|
||||||
|
'Georg Brandl', 'howto')
|
||||||
|
]})
|
||||||
|
def test_latex_toplevel_sectioning_is_part_with_howto(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||||
|
print(result)
|
||||||
|
print(status.getvalue())
|
||||||
|
print(warning.getvalue())
|
||||||
|
assert '\\part{Foo}' in result
|
||||||
|
assert '\\section{Foo A}' in result
|
||||||
|
assert '\\section{Foo B}' in result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx(
|
@pytest.mark.sphinx(
|
||||||
@ -818,6 +871,22 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
|
|||||||
assert '\\chapter{Foo}' in result
|
assert '\\chapter{Foo}' in result
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.sphinx(
|
||||||
|
'latex', testroot='toctree-maxdepth',
|
||||||
|
confoverrides={'latex_toplevel_sectioning': 'chapter',
|
||||||
|
'latex_documents': [
|
||||||
|
('index', 'Python.tex', 'Sphinx Tests Documentation',
|
||||||
|
'Georg Brandl', 'howto')
|
||||||
|
]})
|
||||||
|
def test_latex_toplevel_sectioning_is_chapter_with_howto(app, status, warning):
|
||||||
|
app.builder.build_all()
|
||||||
|
result = (app.outdir / 'Python.tex').text(encoding='utf8')
|
||||||
|
print(result)
|
||||||
|
print(status.getvalue())
|
||||||
|
print(warning.getvalue())
|
||||||
|
assert '\\section{Foo}' in result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.sphinx(
|
@pytest.mark.sphinx(
|
||||||
'latex', testroot='toctree-maxdepth',
|
'latex', testroot='toctree-maxdepth',
|
||||||
confoverrides={'latex_toplevel_sectioning': 'section'})
|
confoverrides={'latex_toplevel_sectioning': 'section'})
|
||||||
|
@ -21,9 +21,9 @@ def test_build(app, status, warning):
|
|||||||
py_undoc = (app.outdir / 'python.txt').text()
|
py_undoc = (app.outdir / 'python.txt').text()
|
||||||
assert py_undoc.startswith('Undocumented Python objects\n'
|
assert py_undoc.startswith('Undocumented Python objects\n'
|
||||||
'===========================\n')
|
'===========================\n')
|
||||||
assert 'test_autodoc\n------------\n' in py_undoc
|
assert 'autodoc_target\n--------------\n' in py_undoc
|
||||||
assert ' * Class -- missing methods:\n' in py_undoc
|
assert ' * Class -- missing methods:\n' in py_undoc
|
||||||
assert ' * process_docstring\n' in py_undoc
|
assert ' * raises\n' in py_undoc
|
||||||
assert ' * function\n' not in py_undoc # these two are documented
|
assert ' * function\n' not in py_undoc # these two are documented
|
||||||
assert ' * Class\n' not in py_undoc # in autodoc.txt
|
assert ' * Class\n' not in py_undoc # in autodoc.txt
|
||||||
|
|
||||||
@ -40,9 +40,9 @@ def test_build(app, status, warning):
|
|||||||
# the key is the full path to the header file, which isn't testable
|
# the key is the full path to the header file, which isn't testable
|
||||||
assert list(undoc_c.values())[0] == set([('function', 'Py_SphinxTest')])
|
assert list(undoc_c.values())[0] == set([('function', 'Py_SphinxTest')])
|
||||||
|
|
||||||
assert 'test_autodoc' in undoc_py
|
assert 'autodoc_target' in undoc_py
|
||||||
assert 'funcs' in undoc_py['test_autodoc']
|
assert 'funcs' in undoc_py['autodoc_target']
|
||||||
assert 'process_docstring' in undoc_py['test_autodoc']['funcs']
|
assert 'raises' in undoc_py['autodoc_target']['funcs']
|
||||||
assert 'classes' in undoc_py['test_autodoc']
|
assert 'classes' in undoc_py['autodoc_target']
|
||||||
assert 'Class' in undoc_py['test_autodoc']['classes']
|
assert 'Class' in undoc_py['autodoc_target']['classes']
|
||||||
assert 'undocmeth' in undoc_py['test_autodoc']['classes']['Class']
|
assert 'undocmeth' in undoc_py['autodoc_target']['classes']['Class']
|
||||||
|
Loading…
Reference in New Issue
Block a user