diff --git a/.travis.yml b/.travis.yml index 7bc822d704..8aaa96ebe9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,6 +25,8 @@ matrix: env: TOXENV=py38 - python: '3.6' env: TOXENV=docs + - python: '3.6' + env: TOXENV=docslint - python: '3.6' env: TOXENV=mypy - python: '3.6' diff --git a/AUTHORS b/AUTHORS index aef4410be2..27c51d1503 100644 --- a/AUTHORS +++ b/AUTHORS @@ -82,6 +82,7 @@ Other contributors, listed alphabetically, are: * Stephen Finucane -- setup command improvements and documentation * Daniel Pizetta -- inheritance diagram improvements * KINEBUCHI Tomohiko -- typing Sphinx as well as docutils +* Adrián Chaves (Gallaecio) -- coverage builder improvements Many thanks for all contributions! diff --git a/CHANGES b/CHANGES index d2a7970468..f4727fc6e3 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Incompatible changes * #6230: The anchor of term in glossary directive is changed if it is consisted by non-ASCII characters * #4550: html: Centering tables by default using CSS +* #6239: latex: xelatex and xeCJK are used for Chinese documents by default Deprecated ---------- @@ -67,6 +68,7 @@ Deprecated * ``sphinx.environment.NoUri`` * ``sphinx.ext.apidoc.format_directive()`` * ``sphinx.ext.apidoc.format_heading()`` +* ``sphinx.ext.apidoc.makename()`` * ``sphinx.ext.autodoc.importer.MockFinder`` * ``sphinx.ext.autodoc.importer.MockLoader`` * ``sphinx.ext.autodoc.importer.mock()`` @@ -106,12 +108,19 @@ Features added * #6289: autodoc: :confval:`autodoc_default_options` now supports ``imported-members`` option * #4777: autodoc: Support coroutine +* #744: autodoc: Support abstractmethod +* #6325: autodoc: Support attributes in __slots__. For dict-style __slots__, + autodoc considers values as a docstring of the attribute +* #6361: autodoc: Add :confval:`autodoc_typehints` to suppress typehints from + signature * #6212 autosummary: Add :confval:`autosummary_imported_members` to display imported members on autosummary * #6271: ``make clean`` is catastrophically broken if building into '.' +* #6363: Support ``%O%`` environment variable in make.bat * #4777: py domain: Add ``:async:`` option to :rst:dir:`py:function` directive * py domain: Add new options to :rst:dir:`py:method` directive + - ``:abstractmethod:`` - ``:async:`` - ``:classmethod:`` - ``:property:`` @@ -120,6 +129,12 @@ Features added * rst domain: Add :rst:dir:`directive:option` directive to describe the option for directive * #6306: html: Add a label to search form for accessability purposes +* #4390: html: Consistent and semantic CSS for signatures +* #6358: The ``rawsource`` property of ``production`` nodes now contains the + full production rule +* #6373: autosectionlabel: Allow suppression of warnings +* coverage: Support a new ``coverage_ignore_pyobjects`` option +* #6239: latex: Support to build Chinese documents Bugs fixed ---------- @@ -129,11 +144,21 @@ Bugs fixed * #6213: ifconfig: contents after headings are not shown * commented term in glossary directive is wrongly recognized * #6299: rst domain: rst:directive directive generates waste space +* #6379: py domain: Module index (py-modindex.html) has duplicate titles * #6331: man: invalid output when doctest follows rubric * #6351: "Hyperlink target is not referenced" message is shown even if referenced * #6165: autodoc: ``tab_width`` setting of docutils has been ignored +* #6347: autodoc: crashes with a plain Tuple on Python 3.6 and 3.5 +* #6311: autosummary: autosummary table gets confused by complex type hints +* #6350: autosummary: confused by an argument having some kind of default value * Generated Makefiles lack a final EOL (refs: #6232) +* #6375: extlinks: Cannot escape angle brackets in link caption +* #6378: linkcheck: Send commonly used User-Agent +* #6387: html search: failed to search document with haiku and scrolls themes +* #6408: html search: Fix the ranking of search results +* #6406: Wrong year is returned for ``SOURCE_DATE_EPOCH`` +* #6402: image directive crashes by unknown image format Testing -------- @@ -152,7 +177,8 @@ Bugs fixed - sphinx.builders.htmlhelp - :confval:`viewcode_import` -* #6208: C++, properly parse full xrefs that happen to have a short xref as prefix. +* #6208: C++, properly parse full xrefs that happen to have a short xref as + prefix * #6220, #6225: napoleon: AttributeError is raised for raised section having references * #6245: circular import error on importing SerializingHTMLBuilder @@ -453,7 +479,8 @@ Release 1.8.5 (released Mar 10, 2019) Bugs fixed ---------- -* LaTeX: Remove extraneous space after author names on PDF title page (refs: #6004) +* LaTeX: Remove extraneous space after author names on PDF title page (refs: + #6004) * #6026: LaTeX: A cross reference to definition list does not work * #6046: LaTeX: ``TypeError`` is raised when invalid latex_elements given * #6067: LaTeX: images having a target are concatenated to next line @@ -481,8 +508,8 @@ Bugs fixed * #5889: LaTeX: user ``numfig_format`` is stripped of spaces and may cause build failure * C++, fix hyperlinks for declarations involving east cv-qualifiers. -* #5755: C++, fix duplicate declaration error on function templates with constraints - in the return type. +* #5755: C++, fix duplicate declaration error on function templates with + constraints in the return type. * C++, parse unary right fold expressions and binary fold expressions. * pycode could not handle egg files on windows * #5928: KeyError: 'DOCUTILSCONFIG' when running build @@ -725,7 +752,8 @@ Deprecated * ``sphinx.writers.latex.Table.caption_footnotetexts`` is deprecated * ``sphinx.writers.latex.Table.header_footnotetexts`` is deprecated * ``sphinx.writers.latex.LaTeXTranslator.footnotestack`` is deprecated -* ``sphinx.writers.latex.LaTeXTranslator.in_container_literal_block`` is deprecated +* ``sphinx.writers.latex.LaTeXTranslator.in_container_literal_block`` is + deprecated * ``sphinx.writers.latex.LaTeXTranslator.next_section_ids`` is deprecated * ``sphinx.writers.latex.LaTeXTranslator.next_hyperlink_ids`` is deprecated * ``sphinx.writers.latex.LaTeXTranslator.restrict_footnote()`` is deprecated @@ -810,12 +838,13 @@ Features added - Add a ``cpp:texpr`` role as a sibling to ``cpp:expr``. - Add support for unions. - - #3593, #2683: add support for anonymous entities using names staring with ``@``. + - #3593, #2683: add support for anonymous entities using names staring with + ``@``. - #5147: add support for (most) character literals. - Cross-referencing entities inside primary templates is supported, and now properly documented. - - #1552: add new cross-referencing format for ``cpp:any`` and ``cpp:func`` roles, - for referencing specific function overloads. + - #1552: add new cross-referencing format for ``cpp:any`` and ``cpp:func`` + roles, for referencing specific function overloads. * #3606: MathJax should be loaded with async attribute * html: Output ``canonical_url`` metadata if :confval:`html_baseurl` set (refs: @@ -872,7 +901,7 @@ Bugs fixed * #4945: i18n: fix lang_COUNTRY not fallback correctly for IndexBuilder. Thanks to Shengjing Zhu. * #4983: productionlist directive generates invalid IDs for the tokens -* #5132: (lualatex) PDF build fails if indexed word starts with Unicode character +* #5132: lualatex: PDF build fails if indexed word starts with Unicode character * #5133: latex: index headings "Symbols" and "Numbers" not internationalized * #5114: sphinx-build: Handle errors on scanning documents * epub: spine has been broken when "self" is listed on toctree (refs: #4611) @@ -1200,19 +1229,21 @@ Features added 1.7.0b1 * C++, handle ``decltype(auto)``. -* #2406: C++, add proper parsing of expressions, including linking of identifiers. +* #2406: C++, add proper parsing of expressions, including linking of + identifiers. * C++, add a ``cpp:expr`` role for inserting inline C++ expressions or types. -* C++, support explicit member instantiations with shorthand ``template`` prefix. +* C++, support explicit member instantiations with shorthand ``template`` prefix * C++, make function parameters linkable, like template params. * #3638: Allow to change a label of reference to equation using ``math_eqref_format`` - * Now :confval:`suppress_warnings` accepts following configurations: - ``ref.python`` (ref: #3866) + * #3872: Add latex key to configure literal blocks caption position in PDF output (refs #3792, #1723) -* In case of missing docstring try to retrieve doc from base classes (ref: #3140) +* In case of missing docstring try to retrieve doc from base classes (ref: + #3140) * #4023: Clarify error message when any role has more than one target. * #3973: epub: allow to override build date * #3972: epub: Sort manifest entries by filename @@ -1400,8 +1431,8 @@ Bugs fixed remote image * #1421: Respect the quiet flag in sphinx-quickstart * #4281: Race conditions when creating output directory -* #4315: For PDF 'howto' documents, ``latex_toplevel_sectioning='part'`` generates - ``\chapter`` commands +* #4315: For PDF 'howto' documents, ``latex_toplevel_sectioning='part'`` + generates ``\chapter`` commands * #4214: Two todolist directives break sphinx-1.6.5 * Fix links to external option docs with intersphinx (refs: #3769) * #4091: Private members not documented without :undoc-members: @@ -1569,16 +1600,19 @@ Incompatible changes * #1061, #2336, #3235: Now generation of autosummary doesn't contain imported members by default. Thanks to Luc Saffre. -* LaTeX ``\includegraphics`` command isn't overloaded: only ``\sphinxincludegraphics`` - has the custom code to fit image to available width if oversized. +* LaTeX ``\includegraphics`` command isn't overloaded: only + ``\sphinxincludegraphics`` has the custom code to fit image to available width + if oversized. * The subclasses of ``sphinx.domains.Index`` should override ``generate()`` method. The default implementation raises NotImplementedError * LaTeX positioned long tables horizontally centered, and short ones - flushed left (no text flow around table.) The position now defaults to center in - both cases, and it will obey Docutils 0.13 ``:align:`` option (refs #3415, #3377) -* option directive also allows all punctuations for the option name (refs: #3366) -* #3413: if :rst:dir:`literalinclude`'s ``:start-after:`` is used, make ``:lines:`` - relative (refs #3412) + flushed left (no text flow around table.) The position now defaults to center + in both cases, and it will obey Docutils 0.13 ``:align:`` option (refs #3415, + #3377) +* option directive also allows all punctuations for the option name (refs: + #3366) +* #3413: if :rst:dir:`literalinclude`'s ``:start-after:`` is used, make + ``:lines:`` relative (refs #3412) * ``literalinclude`` directive does not allow the combination of ``:diff:`` option and other options (refs: #3416) * LuaLaTeX engine uses ``fontspec`` like XeLaTeX. It is advised ``latex_engine @@ -1586,7 +1620,8 @@ Incompatible changes * :confval:`latex_keep_old_macro_names` default value has been changed from ``True`` to ``False``. This means that some LaTeX macros for styling are by default defined only with ``\sphinx..`` prefixed names. (refs: #3429) -* Footer "Continued on next page" of LaTeX longtable's now not framed (refs: #3497) +* Footer "Continued on next page" of LaTeX longtable's now not framed (refs: + #3497) * #3529: The arguments of ``BuildEnvironment.__init__`` is changed * #3082: Use latexmk for pdf (and dvi) targets (Unix-like platforms only) * #3558: Emit warnings if footnotes and citations are not referenced. The @@ -1598,7 +1633,8 @@ Incompatible changes (refs #3550) * ``Builder.env`` is not filled at instantiation * #3594: LaTeX: single raw directive has been considered as block level element -* #3639: If ``html_experimental_html5_writer`` is available, epub builder use it by default. +* #3639: If ``html_experimental_html5_writer`` is available, epub builder use it + by default. * ``Sphinx.add_source_parser()`` raises an error if duplicated 1.6b2 @@ -1646,8 +1682,8 @@ Features added 1.6b1 * #3136: Add ``:name:`` option to the directives in ``sphinx.ext.graphviz`` -* #2336: Add ``imported_members`` option to ``sphinx-autogen`` command to document - imported members. +* #2336: Add ``imported_members`` option to ``sphinx-autogen`` command to + document imported members. * C++, add ``:tparam-line-spec:`` option to templated declarations. When specified, each template parameter will be rendered on a separate line. * #3359: Allow sphinx.js in a user locale dir to override sphinx.js from Sphinx @@ -1670,9 +1706,11 @@ Features added * #3476: setuptools: Support multiple builders * latex: merged cells in LaTeX tables allow code-blocks, lists, blockquotes... as do normal cells (refs: #3435) -* HTML builder uses experimental HTML5 writer if ``html_experimental_html5_writer`` is True - and docutils 0.13 or later is installed. -* LaTeX macros to customize space before and after tables in PDF output (refs #3504) +* HTML builder uses experimental HTML5 writer if + ``html_experimental_html5_writer`` is True and docutils 0.13 or later is + installed. +* LaTeX macros to customize space before and after tables in PDF output (refs + #3504) * #3348: Show decorators in literalinclude and viewcode directives * #3108: Show warning if :start-at: and other literalinclude options does not match to the text @@ -1710,7 +1748,8 @@ Bugs fixed * #1574: Paragraphs in table cell doesn't work in Latex output * #3288: Table with merged headers not wrapping text * #3491: Inconsistent vertical space around table and longtable in PDF -* #3506: Depart functions for all admonitions in HTML writer now properly pass ``node`` to ``depart_admonition``. +* #3506: Depart functions for all admonitions in HTML writer now properly pass + ``node`` to ``depart_admonition``. * #2693: Sphinx latex style file wrongly inhibits colours for section headings for latex+dvi(ps,pdf,pdfmx) * C++, properly look up ``any`` references. @@ -1734,7 +1773,7 @@ Bugs fixed :confval:`html_compact_lists` is True. * The ``make latexpdf`` from 1.6b1 (for GNU/Linux and Mac OS, using ``latexmk``) aborted earlier in case of LaTeX errors than was the case with - 1.5 series, due to hard-coded usage of ``--halt-on-error`` option. (refs #3695) + 1.5 series, due to hard-coded usage of ``--halt-on-error`` option (refs #3695) * #3683: sphinx.websupport module is not provided by default * #3683: Failed to build document if builder.css_file.insert() is called * #3714: viewcode extension not taking ``highlight_code='none'`` in account @@ -1869,7 +1908,8 @@ Bugs fixed * #3507: wrong quotes in latex output for productionlist directive * #3533: Moving from Sphinx 1.3.1 to 1.5.3 breaks LaTeX compilation of links rendered as code -* #2665, #2607: Link names in C++ docfields, and make it possible for other domains. +* #2665, #2607: Link names in C++ docfields, and make it possible for other + domains. * #3542: C++, fix parsing error of non-type template argument with template. * #3065, #3520: python domain fails to recognize nested class * #3575: Problems with pdflatex in a Turkish document built with sphinx has @@ -1949,7 +1989,7 @@ Bugs fixed unserializable exception * #3315: Bibliography crashes on latex build with docclass 'memoir' * #3328: Could not refer rubric implicitly -* #3329: emit warnings if po file is invalid and can't read it. Also writing mo too +* #3329: emit warnings if po file is invalid and can't read it. Also writing mo * #3337: Ugly rendering of definition list term's classifier * #3335: gettext does not extract field_name of a field in a field_list * #2952: C++, fix refs to operator() functions. @@ -1967,7 +2007,8 @@ Bugs fixed * #3308: Parsed-literals don't wrap very long lines with pdf builder (ref #3340) * #3295: Could not import extension sphinx.builders.linkcheck * #3285: autosummary: asterisks are escaped twice -* LaTeX, pass dvipdfm option to geometry package for Japanese documents (ref #3363) +* LaTeX, pass dvipdfm option to geometry package for Japanese documents (ref + #3363) * Fix parselinenos() could not parse left half open range (cf. "-4") @@ -2025,8 +2066,8 @@ Incompatible changes ``index.rst.txt``). * ``sphinx.util.copy_static_entry()`` is now deprecated. Use ``sphinx.util.fileutil.copy_asset()`` instead. -* ``sphinx.util.osutil.filecopy()`` skips copying if the file has not been changed - (ref: #2510, #2753) +* ``sphinx.util.osutil.filecopy()`` skips copying if the file has not been + changed (ref: #2510, #2753) * Internet Explorer 6-8, Opera 12.1x or Safari 5.1+ support is dropped because jQuery version is updated from 1.11.0 to 3.1.0 (ref: #2634, #2773) * QtHelpBuilder doesn't generate search page (ref: #2352) @@ -2036,18 +2077,23 @@ Incompatible changes ``jreport`` and ``jsbook`` as docclass if :confval:`language` is ``ja``. * ``sphinx-quickstart`` now allows a project version is empty -* Fix :download: role on epub/qthelp builder. They ignore the role because they don't support it. -* ``sphinx.ext.viewcode`` doesn't work on epub building by default. ``viewcode_enable_epub`` option +* Fix :download: role on epub/qthelp builder. They ignore the role because they + don't support it. +* ``sphinx.ext.viewcode`` doesn't work on epub building by default. + ``viewcode_enable_epub`` option * ``sphinx.ext.viewcode`` disabled on singlehtml builder. * Use make-mode of ``sphinx-quickstart`` by default. To disable this, use ``-M`` option -* Fix ``genindex.html``, Sphinx's document template, link address to itself to satisfy xhtml standard. +* Fix ``genindex.html``, Sphinx's document template, link address to itself to + satisfy xhtml standard. * Use epub3 builder by default. And the old epub builder is renamed to epub2. -* Fix ``epub`` and ``epub3`` builders that contained links to ``genindex`` even if ``epub_use_index = False``. +* Fix ``epub`` and ``epub3`` builders that contained links to ``genindex`` even + if ``epub_use_index = False``. * ``html_translator_class`` is now deprecated. Use `Sphinx.set_translator()` API instead. * Drop python 2.6 and 3.3 support -* Drop epub3 builder's ``epub3_page_progression_direction`` option (use ``epub3_writing_mode``). +* Drop epub3 builder's ``epub3_page_progression_direction`` option (use + ``epub3_writing_mode``). * #2877: Rename ``latex_elements['footer']`` to ``latex_elements['atendofbody']`` @@ -2182,8 +2228,9 @@ Features added * #2513: A better default settings for XeLaTeX * #3096: ``'maxlistdepth'`` key to work around LaTeX list limitations -* #3060: autodoc supports documentation for attributes of Enum class. Now autodoc render - just the value of Enum attributes instead of Enum attribute representation. +* #3060: autodoc supports documentation for attributes of Enum class. Now + autodoc render just the value of Enum attributes instead of Enum attribute + representation. * Add ``--extensions`` to ``sphinx-quickstart`` to support enable arbitrary extensions from command line (ref: #2904) * #3104, #3122: ``'sphinxsetup'`` for key=value styling of Sphinx LaTeX @@ -2193,7 +2240,8 @@ Features added :confval:`linkcheck_anchors_ignore` * #3083: let Unicode no-break space act like LaTeX ``~`` (fixed #3019) * #3116: allow word wrap in PDF output for inline literals (ref #3110) -* #930: sphinx-apidoc allow wildcards for excluding paths. Thanks to Nick Coghlan. +* #930: sphinx-apidoc allow wildcards for excluding paths. Thanks to Nick + Coghlan. * #3121: add ``inlineliteralwraps`` option to control if inline literal word-wraps in latex @@ -2255,12 +2303,14 @@ Bugs fixed 1.5b1 -* #2432: Fix unwanted * between varargs and keyword only args. Thanks to Alex Grönholm. +* #2432: Fix unwanted * between varargs and keyword only args. Thanks to Alex + Grönholm. * #3062: Failed to build PDF using 1.5a2 (undefined ``\hypersetup`` for Japanese documents since PR#3030) * Better rendering of multiline signatures in html. * #777: LaTeX output "too deeply nested" (ref #3096) -* Let LaTeX image inclusion obey ``scale`` before textwidth fit (ref #2865, #3059) +* Let LaTeX image inclusion obey ``scale`` before textwidth fit (ref #2865, + #3059) * #3019: LaTeX fails on description of C function with arguments (ref #3083) * fix latex inline literals where ``< > -`` gobbled a space @@ -2280,8 +2330,8 @@ Bugs fixed * #1843: Fix documentation of descriptor classes that have a custom metaclass. Thanks to Erik Bray. * #3190: util.split_docinfo fails to parse multi-line field bodies -* #3024, #3037: In Python3, application.Sphinx._log crushed when the log message cannot - be encoded into console encoding. +* #3024, #3037: In Python3, application.Sphinx._log crushed when the log message + cannot be encoded into console encoding. Testing -------- @@ -2301,7 +2351,8 @@ Bugs fixed * #3068: Allow the '=' character in the -D option of sphinx-build.py * #3074: ``add_source_parser()`` crashes in debug mode * #3135: ``sphinx.ext.autodoc`` crashes with plain Callable -* #3150: Fix query word splitter in JavaScript. It behaves as same as Python's regular expression. +* #3150: Fix query word splitter in JavaScript. It behaves as same as Python's + regular expression. * #3093: gettext build broken on substituted images. * #3093: gettext build broken on image node under ``note`` directive. * imgmath: crashes on showing error messages if image generation failed @@ -2329,10 +2380,13 @@ Bugs fixed * #2902: jsdump.loads fails to load search index if keywords starts with underscore * #2900: Fix epub content.opf: add auto generated orphan files to spine. -* #2899: Fix ``hasdoc()`` function in Jinja2 template. It will detect ``genindex``, ``search`` also. -* #2901: Fix epub result: skip creating links from image tags to original image files. +* #2899: Fix ``hasdoc()`` function in Jinja2 template. It will detect + ``genindex``, ``search`` also. +* #2901: Fix epub result: skip creating links from image tags to original image + files. * #2917: inline code is hyphenated on HTML -* #1462: autosummary warns for namedtuple with attribute with trailing underscore +* #1462: autosummary warns for namedtuple with attribute with trailing + underscore * Could not reference equations if ``:nowrap:`` option specified * #2873: code-block overflow in latex (due to commas) * #1060, #2056: sphinx.ext.intersphinx: broken links are generated if relative @@ -2349,29 +2403,35 @@ Release 1.4.6 (released Aug 20, 2016) Incompatible changes -------------------- -* #2867: linkcheck builder crashes with six-1.4. Now Sphinx depends on six-1.5 or - later +* #2867: linkcheck builder crashes with six-1.4. Now Sphinx depends on six-1.5 + or later Bugs fixed ---------- * applehelp: Sphinx crashes if ``hiutil`` or ``codesign`` commands not found -* Fix ``make clean`` abort issue when build dir contains regular files like ``DS_Store``. +* Fix ``make clean`` abort issue when build dir contains regular files like + ``DS_Store``. * Reduce epubcheck warnings/errors: * Fix DOCTYPE to html5 * Change extension from .html to .xhtml. * Disable search page on epub results -* #2778: Fix autodoc crashes if obj.__dict__ is a property method and raises exception +* #2778: Fix autodoc crashes if obj.__dict__ is a property method and raises + exception * Fix duplicated toc in epub3 output. * #2775: Fix failing linkcheck with servers not supporting identity encoding * #2833: Fix formatting instance annotations in ext.autodoc. -* #1911: ``-D`` option of ``sphinx-build`` does not override the ``extensions`` variable -* #2789: `sphinx.ext.intersphinx` generates wrong hyperlinks if the inventory is given -* parsing errors for caption of code-blocks are displayed in document (ref: #2845) +* #1911: ``-D`` option of ``sphinx-build`` does not override the ``extensions`` + variable +* #2789: `sphinx.ext.intersphinx` generates wrong hyperlinks if the inventory is + given +* parsing errors for caption of code-blocks are displayed in document + (ref: #2845) * #2846: ``singlehtml`` builder does not include figure numbers -* #2816: Fix data from builds cluttering the ``Domain.initial_data`` class attributes +* #2816: Fix data from builds cluttering the ``Domain.initial_data`` class + attributes Release 1.4.5 (released Jul 13, 2016) ===================================== @@ -2390,7 +2450,7 @@ Features added -------------- * new config option ``latex_keep_old_macro_names``, defaults to True. If False, - lets macros (for text styling) be defined only with ``\sphinx``-prefixed names. + lets macros (for text styling) be defined only with ``\sphinx``-prefixed names * latex writer allows user customization of "shadowed" boxes (topics), via three length variables. * woff-format web font files now supported by the epub builder. @@ -2400,7 +2460,8 @@ Bugs fixed * jsdump fix for python 3: fixes the HTML search on python > 3 * #2676: (latex) Error with verbatim text in captions since Sphinx 1.4.4 -* #2629: memoir class crashes LaTeX. Fixed ``by latex_keep_old_macro_names=False`` (ref 2675) +* #2629: memoir class crashes LaTeX. Fixed by + ``latex_keep_old_macro_names=False`` (ref 2675) * #2684: `sphinx.ext.intersphinx` crashes with six-1.4.1 * #2679: ``float`` package needed for ``'figure_align': 'H'`` latex option * #2671: image directive may lead to inconsistent spacing in pdf @@ -2408,10 +2469,12 @@ Bugs fixed * #2479: `sphinx.ext.viewcode` uses python2 highlighter by default * #2700: HtmlHelp builder has hard coded index.html * latex, since 1.4.4 inline literal text is followed by spurious space -* #2722: C++, fix id generation for var/member declarations to include namespaces. +* #2722: C++, fix id generation for var/member declarations to include + namespaces. * latex, images (from image directive) in lists or quoted blocks did not obey indentation (fixed together with #2671) -* #2733: since Sphinx-1.4.4 ``make latexpdf`` generates lots of hyperref warnings +* #2733: since Sphinx-1.4.4 ``make latexpdf`` generates lots of hyperref + warnings * #2731: `sphinx.ext.autodoc` does not access propertymethods which raises any exceptions * #2666: C++, properly look up nested names involving constructors. @@ -2459,13 +2522,16 @@ Bugs fixed * #2530: got "Counter too large" error on building PDF if large numbered footnotes existed in admonitions -* ``width`` option of figure directive does not work if ``align`` option specified at same time (ref: #2595) +* ``width`` option of figure directive does not work if ``align`` option + specified at same time (ref: #2595) * #2590: The ``inputenc`` package breaks compiling under lualatex and xelatex * #2540: date on latex front page use different font -* Suppress "document isn't included in any toctree" warning if the document is included (ref: #2603) +* Suppress "document isn't included in any toctree" warning if the document is + included (ref: #2603) * #2614: Some tables in PDF output will end up shifted if user sets non zero \parindent in preamble -* #2602: URL redirection breaks the hyperlinks generated by `sphinx.ext.intersphinx` +* #2602: URL redirection breaks the hyperlinks generated by + `sphinx.ext.intersphinx` * #2613: Show warnings if merged extensions are loaded * #2619: make sure amstext LaTeX package always loaded (ref: d657225, 488ee52, 9d82cad and #2615) @@ -2478,7 +2544,8 @@ Release 1.4.2 (released May 29, 2016) Features added -------------- -* Now :confval:`suppress_warnings` accepts following configurations (ref: #2451, #2466): +* Now :confval:`suppress_warnings` accepts following configurations + (ref: #2451, #2466): - ``app.add_node`` - ``app.add_directive`` @@ -2505,14 +2572,17 @@ Bugs fixed * #2370: the equations are slightly misaligned in LaTeX writer * #1817, #2077: suppress pep8 warnings on conf.py generated by sphinx-quickstart * #2407: building docs crash if document includes large data image URIs -* #2436: Sphinx does not check version by :confval:`needs_sphinx` if loading extensions failed +* #2436: Sphinx does not check version by :confval:`needs_sphinx` if loading + extensions failed * #2397: Setup shorthandoff for Turkish documents * #2447: VerbatimBorderColor wrongly used also for captions of PDF -* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex builders). +* #2456: C++, fix crash related to document merging (e.g., singlehtml and Latex + builders). * #2446: latex(pdf) sets local tables of contents (or more generally topic nodes) in unbreakable boxes, causes overflow at bottom * #2476: Omit MathJax markers if :nowrap: is given -* #2465: latex builder fails in case no caption option is provided to toctree directive +* #2465: latex builder fails in case no caption option is provided to toctree + directive * Sphinx crashes if self referenced toctree found * #2481: spelling mistake for mecab search splitter. Thanks to Naoki Sato. * #2309: Fix could not refer "indirect hyperlink targets" by ref-role @@ -2522,22 +2592,28 @@ Bugs fixed * #1534: Word wrap long lines in Latex verbatim blocks * #2460: too much white space on top of captioned literal blocks in PDF output * Show error reason when multiple math extensions are loaded (ref: #2499) -* #2483: any figure number was not assigned if figure title contains only non text objects +* #2483: any figure number was not assigned if figure title contains only non + text objects * #2501: Unicode subscript numbers are normalized in LaTeX * #2492: Figure directive with :figwidth: generates incorrect Latex-code -* The caption of figure is always put on center even if ``:align:`` was specified +* The caption of figure is always put on center even if ``:align:`` was + specified * #2526: LaTeX writer crashes if the section having only images -* #2522: Sphinx touches mo files under installed directory that caused permission error. -* #2536: C++, fix crash when an immediately nested scope has the same name as the current scope. +* #2522: Sphinx touches mo files under installed directory that caused + permission error. +* #2536: C++, fix crash when an immediately nested scope has the same name as + the current scope. * #2555: Fix crash on any-references with unicode. * #2517: wrong bookmark encoding in PDF if using LuaLaTeX * #2521: generated Makefile causes BSD make crashed if sphinx-build not found * #2470: ``typing`` backport package causes autodoc errors with python 2.7 -* ``sphinx.ext.intersphinx`` crashes if non-string value is used for key of `intersphinx_mapping` +* ``sphinx.ext.intersphinx`` crashes if non-string value is used for key of + `intersphinx_mapping` * #2518: `intersphinx_mapping` disallows non alphanumeric keys * #2558: unpack error on devhelp builder * #2561: Info builder crashes when a footnote contains a link -* #2565: The descriptions of objects generated by ``sphinx.ext.autosummary`` overflow lines at LaTeX writer +* #2565: The descriptions of objects generated by ``sphinx.ext.autosummary`` + overflow lines at LaTeX writer * Extend pdflatex config in sphinx.sty to subparagraphs (ref: #2551) * #2445: `rst_prolog` and `rst_epilog` affect to non reST sources * #2576: ``sphinx.ext.imgmath`` crashes if subprocess raises error @@ -2572,8 +2648,8 @@ Bugs fixed ---------- * C++, added support for ``extern`` and ``thread_local``. -* C++, type declarations are now using the prefixes ``typedef``, ``using``, and ``type``, - depending on the style of declaration. +* C++, type declarations are now using the prefixes ``typedef``, ``using``, and + ``type``, depending on the style of declaration. * #2413: C++, fix crash on duplicate declarations * #2394: Sphinx crashes when html_last_updated_fmt is invalid * #2408: dummy builder not available in Makefile and make.bat @@ -2592,27 +2668,28 @@ Release 1.4 (released Mar 28, 2016) Incompatible changes -------------------- -* Drop ``PorterStemmer`` package support. Use ``PyStemmer`` instead of ``PorterStemmer`` - to accelerate stemming. +* Drop ``PorterStemmer`` package support. Use ``PyStemmer`` instead of + ``PorterStemmer`` to accelerate stemming. * sphinx_rtd_theme has become optional. Please install it manually. Refs #2087, #2086, #1845 and #2097. Thanks to Victor Zverovich. -* #2231: Use DUrole instead of DUspan for custom roles in LaTeX writer. It enables to take - title of roles as an argument of custom macros. -* #2022: 'Thumbs.db' and '.DS_Store' are added to `exclude_patterns` default values in - conf.py that will be provided on sphinx-quickstart. -* #2027, #2208: The ``html_title`` accepts string values only. And The None value cannot be - accepted. +* #2231: Use DUrole instead of DUspan for custom roles in LaTeX writer. It + enables to take title of roles as an argument of custom macros. +* #2022: 'Thumbs.db' and '.DS_Store' are added to `exclude_patterns` default + values in conf.py that will be provided on sphinx-quickstart. +* #2027, #2208: The ``html_title`` accepts string values only. And The None + value cannot be accepted. * ``sphinx.ext.graphviz``: show graph image in inline by default -* #2060, #2224: The ``manpage`` role now generate ``sphinx.addnodes.manpage`` node instead - of ``sphinx.addnodes.literal_emphasis`` node. -* #2022: :confval:`html_extra_path` also copies dotfiles in the extra directory, and - refers to :confval:`exclude_patterns` to exclude extra files and directories. -* #2300: enhance autoclass:: to use the docstring of __new__ if __init__ method's is missing - of empty -* #2251: Previously, under glossary directives, multiple terms for one definition are - converted into single ``term`` node and the each terms in the term node are separated - by ``termsep`` node. In new implementation, each terms are converted into individual - ``term`` nodes and ``termsep`` node is removed. +* #2060, #2224: The ``manpage`` role now generate ``sphinx.addnodes.manpage`` + node instead of ``sphinx.addnodes.literal_emphasis`` node. +* #2022: :confval:`html_extra_path` also copies dotfiles in the extra directory, + and refers to :confval:`exclude_patterns` to exclude extra files and + directories. +* #2300: enhance autoclass:: to use the docstring of __new__ if __init__ + method's is missing of empty +* #2251: Previously, under glossary directives, multiple terms for one + definition are converted into single ``term`` node and the each terms in the + term node are separated by ``termsep`` node. In new implementation, each terms + are converted into individual ``term`` nodes and ``termsep`` node is removed. By this change, output layout of every builders are changed a bit. * The default highlight language is now Python 3. This means that source code is highlighted as Python 3 (which is mostly a superset of Python 2), and no @@ -2620,13 +2697,15 @@ Incompatible changes add ``highlight_language = "python"`` to conf.py. * `Locale Date Markup Language `_ like - ``"MMMM dd, YYYY"`` is default format for `today_fmt` and `html_last_updated_fmt`. - However strftime format like ``"%B %d, %Y"`` is also supported for backward - compatibility until Sphinx-1.5. Later format will be disabled from Sphinx-1.5. + ``"MMMM dd, YYYY"`` is default format for `today_fmt` and + `html_last_updated_fmt`. However strftime format like ``"%B %d, %Y"`` is also + supported for backward compatibility until Sphinx-1.5. Later format will be + disabled from Sphinx-1.5. * #2327: ``latex_use_parts`` is deprecated now. Use `latex_toplevel_sectioning` instead. * #2337: Use ``\url{URL}`` macro instead of ``\href{URL}{URL}`` in LaTeX writer. -* #1498: manpage writer: don't make whole of item in definition list bold if it includes strong node. +* #1498: manpage writer: don't make whole of item in definition list bold if it + includes strong node. * #582: Remove hint message from quick search box for html output. * #2378: Sphinx now bundles newfloat.sty @@ -2637,8 +2716,10 @@ Features added an element is already present (built-in or added by another extension). * #1909: Add "doc" references to Intersphinx inventories. * C++ type alias support (e.g., ``.. type:: T = int``). -* C++ template support for classes, functions, type aliases, and variables (#1729, #1314). -* C++, added new scope management directives ``namespace-push`` and ``namespace-pop``. +* C++ template support for classes, functions, type aliases, and variables + (#1729, #1314). +* C++, added new scope management directives ``namespace-push`` and + ``namespace-pop``. * #1970: Keyboard shortcuts to navigate Next and Previous topics * Intersphinx: Added support for fetching Intersphinx inventories with URLs using HTTP basic auth. @@ -2652,43 +2733,54 @@ Features added * #2170: Support for Chinese language search index. * #2214: Add sphinx.ext.githubpages to publish the docs on GitHub Pages * #1030: Make page reference names for latex_show_pagerefs translatable -* #2162: Add Sphinx.add_source_parser() to add source_suffix and source_parsers from extension +* #2162: Add Sphinx.add_source_parser() to add source_suffix and source_parsers + from extension * #2207: Add sphinx.parsers.Parser class; a base class for new parsers -* #656: Add ``graphviz_dot`` option to graphviz directives to switch the ``dot`` command +* #656: Add ``graphviz_dot`` option to graphviz directives to switch the ``dot`` + command * #1939: Added the ``dummy`` builder: syntax check without output. -* #2230: Add ``math_number_all`` option to number all displayed math in math extensions +* #2230: Add ``math_number_all`` option to number all displayed math in math + extensions * #2235: ``needs_sphinx`` supports micro version comparison * #2282: Add "language" attribute to html tag in the "basic" theme * #1779: Add EPUB 3 builder * #1751: Add :confval:`todo_link_only` to avoid file path and line indication on :rst:dir:`todolist`. Thanks to Francesco Montesano. * #2199: Use ``imagesize`` package to obtain size of images. -* #1099: Add configurable retries to the linkcheck builder. Thanks to Alex Gaynor. - Also don't check anchors starting with ``!``. -* #2300: enhance autoclass:: to use the docstring of __new__ if __init__ method's is missing - of empty -* #1858: Add Sphinx.add_enumerable_node() to add enumerable nodes for numfig feature +* #1099: Add configurable retries to the linkcheck builder. Thanks to Alex + Gaynor. Also don't check anchors starting with ``!``. +* #2300: enhance autoclass:: to use the docstring of __new__ if __init__ + method's is missing of empty +* #1858: Add Sphinx.add_enumerable_node() to add enumerable nodes for numfig + feature * #1286, #2099: Add ``sphinx.ext.autosectionlabel`` extension to allow reference sections using its title. Thanks to Tadhg O'Higgins. * #1854: Allow to choose Janome for Japanese splitter. * #1853: support custom text splitter on html search with ``language='ja'``. -* #2320: classifier of glossary terms can be used for index entries grouping key. - The classifier also be used for translation. See also :ref:`glossary-directive`. -* #2308: Define ``\tablecontinued`` macro to redefine the style of continued label for - longtables. -* Select an image by similarity if multiple images are globbed by ``.. image:: filename.*`` -* #1921: Support figure substitutions by :confval:`language` and :confval:`figure_language_filename` -* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call PassOptionsToPackages - in early stage of preambles. +* #2320: classifier of glossary terms can be used for index entries grouping key + The classifier also be used for translation. See also + :ref:`glossary-directive`. +* #2308: Define ``\tablecontinued`` macro to redefine the style of continued + label for longtables. +* Select an image by similarity if multiple images are globbed by + ``.. image:: filename.*`` +* #1921: Support figure substitutions by :confval:`language` and + :confval:`figure_language_filename` +* #2245: Add ``latex_elements["passoptionstopackages"]`` option to call + PassOptionsToPackages in early stage of preambles. * #2340: Math extension: support alignment of multiple equations for MathJax. -* #2338: Define ``\titleref`` macro to redefine the style of ``title-reference`` roles. -* Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of `menuselection` roles. +* #2338: Define ``\titleref`` macro to redefine the style of ``title-reference`` + roles. +* Define ``\menuselection`` and ``\accelerator`` macros to redefine the style of + `menuselection` roles. * Define ``\crossref`` macro to redefine the style of references * #2301: Texts in the classic html theme should be hyphenated. * #2355: Define ``\termref`` macro to redefine the style of ``term`` roles. -* Add :confval:`suppress_warnings` to suppress arbitrary warning message (experimental) +* Add :confval:`suppress_warnings` to suppress arbitrary warning message + (experimental) * #2229: Fix no warning is given for unknown options -* #2327: Add `latex_toplevel_sectioning` to switch the top level sectioning of LaTeX document. +* #2327: Add `latex_toplevel_sectioning` to switch the top level sectioning of + LaTeX document. Bugs fixed ---------- @@ -2700,11 +2792,12 @@ Bugs fixed * C++, fix parsing of types prefixed with 'enum'. * #2023: Dutch search support uses Danish stemming info. * C++, add support for user-defined literals. -* #1804: Now html output wraps overflowed long-line-text in the sidebar. Thanks to - Hassen ben tanfous. +* #1804: Now html output wraps overflowed long-line-text in the sidebar. Thanks + to Hassen ben tanfous. * #2183: Fix porterstemmer causes ``make json`` to fail. * #1899: Ensure list is sent to OptParse. -* #2164: Fix wrong check for pdftex inside sphinx.sty (for graphicx package option). +* #2164: Fix wrong check for pdftex inside sphinx.sty (for graphicx package + option). * #2165, #2218: Remove faulty and non-need conditional from sphinx.sty. * Fix broken LaTeX code is generated if unknown language is given * #1944: Fix rst_prolog breaks file-wide metadata @@ -2715,33 +2808,40 @@ Bugs fixed * #794: Fix date formatting in latex output is not localized * Remove ``image/gif`` from supported_image_types of LaTeX writer (#2272) * Fix ValueError is raised if LANGUAGE is empty string -* Fix unpack warning is shown when the directives generated from ``Sphinx.add_crossref_type`` is used -* The default highlight language is now ``default``. This means that source code - is highlighted as Python 3 (which is mostly a superset of Python 2) if possible. - To get the old behavior back, add ``highlight_language = "python"`` to conf.py. +* Fix unpack warning is shown when the directives generated from + ``Sphinx.add_crossref_type`` is used +* The default highlight language is now ``default``. This means that source + code is highlighted as Python 3 (which is mostly a superset of Python 2) if + possible. To get the old behavior back, add ``highlight_language = "python"`` + to conf.py. * #2329: Refresh environment forcedly if source directory has changed. -* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option from - xcolor package -* Fix the confval type checker emits warnings if unicode is given to confvals which expects string value +* #2331: Fix code-blocks are filled by block in dvi; remove ``xcdraw`` option + from xcolor package +* Fix the confval type checker emits warnings if unicode is given to confvals + which expects string value * #2360: Fix numref in LaTeX output is broken * #2361: Fix additional paragraphs inside the "compound" directive are indented * #2364: Fix KeyError 'rootSymbol' on Sphinx upgrade from older version. * #2348: Move amsmath and amssymb to before fontpkg on LaTeX writer. * #2368: Ignore emacs lock files like ``.#foo.rst`` by default. -* #2262: literal_block and its caption has been separated by pagebreak in LaTeX output. -* #2319: Fix table counter is overridden by code-block's in LaTeX. Thanks to jfbu. +* #2262: literal_block and its caption has been separated by pagebreak in LaTeX + output. +* #2319: Fix table counter is overridden by code-block's in LaTeX. Thanks to + jfbu. * Fix unpack warning if combined with 3rd party domain extensions. * #1153: Fix figures in sidebar causes latex build error. * #2358: Fix user-preamble could not override the tocdepth definition. -* #2358: Reduce tocdepth if ``part`` or ``chapter`` is used for top_sectionlevel. +* #2358: Reduce tocdepth if ``part`` or ``chapter`` is used for top_sectionlevel * #2351: Fix footnote spacing -* #2363: Fix ``toctree()`` in templates generates broken links in SingleHTMLBuilder. +* #2363: Fix ``toctree()`` in templates generates broken links in + SingleHTMLBuilder. * #2366: Fix empty hyperref is generated on toctree in HTML builder. Documentation ------------- -* #1757: Fix for usage of :confval:`html_last_updated_fmt`. Thanks to Ralf Hemmecke. +* #1757: Fix for usage of :confval:`html_last_updated_fmt`. Thanks to Ralf + Hemmecke. Release 1.3.6 (released Feb 29, 2016) @@ -2750,8 +2850,9 @@ Release 1.3.6 (released Feb 29, 2016) Features added -------------- -* #1873, #1876, #2278: Add ``page_source_suffix`` html context variable. This should be - introduced with :confval:`source_parsers` feature. Thanks for Eric Holscher. +* #1873, #1876, #2278: Add ``page_source_suffix`` html context variable. This + should be introduced with :confval:`source_parsers` feature. Thanks for Eric + Holscher. Bugs fixed @@ -2760,13 +2861,16 @@ Bugs fixed * #2265: Fix babel is used in spite of disabling it on ``latex_elements`` * #2295: Avoid mutating dictionary errors while enumerating members in autodoc with Python 3 -* #2291: Fix pdflatex "Counter too large" error from footnotes inside tables of contents +* #2291: Fix pdflatex "Counter too large" error from footnotes inside tables of + contents * #2292: Fix some footnotes disappear from LaTeX output -* #2287: ``sphinx.transforms.Locale`` always uses rst parser. Sphinx i18n feature should - support parsers that specified source_parsers. -* #2290: Fix ``sphinx.ext.mathbase`` use of amsfonts may break user choice of math fonts +* #2287: ``sphinx.transforms.Locale`` always uses rst parser. Sphinx i18n + feature should support parsers that specified source_parsers. +* #2290: Fix ``sphinx.ext.mathbase`` use of amsfonts may break user choice of + math fonts * #2324: Print a hint how to increase the recursion limit when it is hit. -* #1565, #2229: Revert new warning; the new warning will be triggered from version 1.4 on. +* #1565, #2229: Revert new warning; the new warning will be triggered from + version 1.4 on. * #2329: Refresh environment forcedly if source directory has changed. * #2019: Fix the domain objects in search result are not escaped @@ -2784,11 +2888,11 @@ Bugs fixed * #2243: Ignore strange docstring types for classes, do not crash * #2247: Fix #2205 breaks make html for definition list with classifiers that contains regular-expression like string -* #1565: Sphinx will now emit a warning that highlighting was skipped if the syntax - is incorrect for `code-block`, `literalinclude` and so on. +* #1565: Sphinx will now emit a warning that highlighting was skipped if the + syntax is incorrect for `code-block`, `literalinclude` and so on. * #2211: Fix paragraphs in table cell doesn't work in Latex output -* #2253: ``:pyobject:`` option of ``literalinclude`` directive can't detect indented - body block when the block starts with blank or comment lines. +* #2253: ``:pyobject:`` option of ``literalinclude`` directive can't detect + indented body block when the block starts with blank or comment lines. * Fix TOC is not shown when no ``:maxdepth:`` for toctrees (ref: #771) * Fix warning message for ``:numref:`` if target is in orphaned doc (ref: #2244) @@ -2808,23 +2912,27 @@ Bugs fixed * #2168: Fix raw directive does not work for text writer * #2171: Fix cannot linkcheck url with unicode * #2182: LaTeX: support image file names with more than 1 dots -* #2189: Fix previous sibling link for first file in subdirectory uses last file, not - intended previous from root toctree +* #2189: Fix previous sibling link for first file in subdirectory uses last + file, not intended previous from root toctree * #2003: Fix decode error under python2 (only) when ``make linkcheck`` is run * #2186: Fix LaTeX output of \mathbb in math * #1480, #2188: LaTeX: Support math in section titles * #2071: Fix same footnote in more than two section titles => LaTeX/PDF Bug -* #2040: Fix UnicodeDecodeError in sphinx-apidoc when author contains non-ascii characters -* #2193: Fix shutil.SameFileError if source directory and destination directory are same -* #2178: Fix unparsable C++ cross-reference when referencing a function with :cpp:any: +* #2040: Fix UnicodeDecodeError in sphinx-apidoc when author contains non-ascii + characters +* #2193: Fix shutil.SameFileError if source directory and destination directory + are same +* #2178: Fix unparsable C++ cross-reference when referencing a function with + :cpp:any: * #2206: Fix Sphinx latex doc build failed due to a footnotes * #2201: Fix wrong table caption for tables with over 30 rows * #2213: Set
in the classic theme to fit with

-* #1815: Fix linkcheck does not raise an exception if warniserror set to true and link is - broken +* #1815: Fix linkcheck does not raise an exception if warniserror set to true + and link is broken * #2197: Fix slightly cryptic error message for missing index.rst file * #1894: Unlisted phony targets in quickstart Makefile -* #2125: Fix unifies behavior of collapsed fields (``GroupedField`` and ``TypedField``) +* #2125: Fix unifies behavior of collapsed fields (``GroupedField`` and + ``TypedField``) * #1408: Check latex_logo validity before copying * #771: Fix latex output doesn't set tocdepth * #1820: On Windows, console coloring is broken with colorama version 0.3.3. @@ -2842,9 +2950,9 @@ Bugs fixed * #2062: Escape characters in doctests are treated incorrectly with Python 2. * #2225: Fix if the option does not begin with dash, linking is not performed * #2226: Fix math is not HTML-encoded when :nowrap: is given (jsmath, mathjax) -* #1601, #2220: 'any' role breaks extended domains behavior. Affected extensions doesn't - support resolve_any_xref and resolve_xref returns problematic node instead of None. - sphinxcontrib-httpdomain is one of them. +* #1601, #2220: 'any' role breaks extended domains behavior. Affected extensions + doesn't support resolve_any_xref and resolve_xref returns problematic node + instead of None. sphinxcontrib-httpdomain is one of them. * #2229: Fix no warning is given for unknown options Release 1.3.3 (released Dec 2, 2015) @@ -2855,8 +2963,8 @@ Bugs fixed * #2177: Fix parallel hangs * #2012: Fix exception occurred if ``numfig_format`` is invalid -* #2142: Provide non-minified JS code in ``sphinx/search/non-minified-js/*.js`` for - source distribution on PyPI. +* #2142: Provide non-minified JS code in ``sphinx/search/non-minified-js/*.js`` + for source distribution on PyPI. * #2148: Error while building devhelp target with non-ASCII document. @@ -2871,24 +2979,27 @@ Features added Bugs fixed ---------- -* #1976: Avoid "2.0" version of Babel because it doesn't work with Windows environment. -* Add a "default.css" stylesheet (which imports "classic.css") for compatibility. +* #1976: Avoid "2.0" version of Babel because it doesn't work with Windows + environment. +* Add a "default.css" stylesheet (which imports "classic.css") for compatibility * #1788: graphviz extension raises exception when caption option is present. -* #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following - lines after class definitions +* #1789: ``:pyobject:`` option of ``literalinclude`` directive includes + following lines after class definitions * #1790: ``literalinclude`` strips empty lines at the head and tail -* #1802: load plugin themes automatically when theme.conf use it as 'inherit'. Thanks to - Takayuki Hirai. -* #1794: custom theme extended from alabaster or sphinx_rtd_theme can't find base theme. +* #1802: load plugin themes automatically when theme.conf use it as 'inherit'. + Thanks to Takayuki Hirai. +* #1794: custom theme extended from alabaster or sphinx_rtd_theme can't find + base theme. * #1834: compatibility for docutils-0.13: handle_io_errors keyword argument for docutils.io.FileInput cause TypeError. -* #1823: '.' as for sphinx-apidoc cause an unfriendly error. Now '.' - is converted to absolute path automatically. +* #1823: '.' as for sphinx-apidoc cause an unfriendly error. Now + '.' is converted to absolute path automatically. * Fix a crash when setting up extensions which do not support metadata. * #1784: Provide non-minified JS code in ``sphinx/search/non-minified-js/*.js`` -* #1822, #1892: Fix regression for #1061. autosummary can't generate doc for imported - members since sphinx-1.3b3. Thanks to Eric Larson. -* #1793, #1819: "see also" misses a linebreak in text output. Thanks to Takayuki Hirai. +* #1822, #1892: Fix regression for #1061. autosummary can't generate doc for + imported members since sphinx-1.3b3. Thanks to Eric Larson. +* #1793, #1819: "see also" misses a linebreak in text output. Thanks to Takayuki + Hirai. * #1780, #1866: "make text" shows "class" keyword twice. Thanks to Takayuki Hirai. * #1871: Fix for LaTeX output of tables with one column and multirows. @@ -2900,36 +3011,40 @@ Bugs fixed * #1923: Use babel features only if the babel latex element is nonempty. * #1942: Fix a KeyError in websupport. * #1903: Fix strange id generation for glossary terms. -* ``make text`` will crush if a definition list item has more than 1 classifiers as: - ``term : classifier1 : classifier2``. -* #1855: make gettext generates broken po file for definition lists with classifier. -* #1869: Fix problems when dealing with files containing non-ASCII characters. Thanks to - Marvin Schmidt. +* ``make text`` will crush if a definition list item has more than 1 classifiers + as: ``term : classifier1 : classifier2``. +* #1855: make gettext generates broken po file for definition lists with + classifier. +* #1869: Fix problems when dealing with files containing non-ASCII characters. + Thanks to Marvin Schmidt. * #1798: Fix building LaTeX with references in titles. * #1725: On py2 environment, doctest with using non-ASCII characters causes ``'ascii' codec can't decode byte`` exception. * #1540: Fix RuntimeError with circular referenced toctree * #1983: i18n translation feature breaks references which uses section name. * #1990: Use caption of toctree to title of \tableofcontents in LaTeX -* #1987: Fix ampersand is ignored in ``:menuselection:`` and ``:guilabel:`` on LaTeX builder -* #1994: More supporting non-standard parser (like recommonmark parser) for Translation and - WebSupport feature. Now node.rawsource is fall backed to node.astext() during docutils - transforming. -* #1989: "make blahblah" on Windows indicate help messages for sphinx-build every time. - It was caused by wrong make.bat that generated by Sphinx-1.3.0/1.3.1. -* On Py2 environment, conf.py that is generated by sphinx-quickstart should have u prefixed - config value for 'version' and 'release'. -* #2102: On Windows + Py3, using ``|today|`` and non-ASCII date format will raise - UnicodeEncodeError. -* #1974: UnboundLocalError: local variable 'domain' referenced before assignment when - using `any` role and `sphinx.ext.intersphinx` in same time. -* #2121: multiple words search doesn't find pages when words across on the page title and - the page content. -* #1884, #1885: plug-in html themes cannot inherit another plug-in theme. Thanks to - Suzumizaki. +* #1987: Fix ampersand is ignored in ``:menuselection:`` and ``:guilabel:`` + on LaTeX builder +* #1994: More supporting non-standard parser (like recommonmark parser) for + Translation and WebSupport feature. Now node.rawsource is fall backed to + node.astext() during docutils transforming. +* #1989: "make blahblah" on Windows indicate help messages for sphinx-build + every time. It was caused by wrong make.bat that generated by + Sphinx-1.3.0/1.3.1. +* On Py2 environment, conf.py that is generated by sphinx-quickstart should have + u prefixed config value for 'version' and 'release'. +* #2102: On Windows + Py3, using ``|today|`` and non-ASCII date format will + raise UnicodeEncodeError. +* #1974: UnboundLocalError: local variable 'domain' referenced before assignment + when using `any` role and `sphinx.ext.intersphinx` in same time. +* #2121: multiple words search doesn't find pages when words across on the page + title and the page content. +* #1884, #1885: plug-in html themes cannot inherit another plug-in theme. Thanks + to Suzumizaki. * #1818: `sphinx.ext.todo` directive generates broken html class attribute as - 'admonition-' when :confval:`language` is specified with non-ASCII linguistic area like - 'ru' or 'ja'. To fix this, now ``todo`` directive can use ``:class:`` option. + 'admonition-' when :confval:`language` is specified with non-ASCII linguistic + area like 'ru' or 'ja'. To fix this, now ``todo`` directive can use + ``:class:`` option. * #2140: Fix footnotes in table has broken in LaTeX * #2127: MecabBinder for html searching feature doesn't work with Python 3. Thanks to Tomoko Uchida. @@ -2943,7 +3058,8 @@ Bugs fixed * #1769: allows generating quickstart files/dirs for destination dir that doesn't overwrite existent files/dirs. Thanks to WAKAYAMA shirou. -* #1773: sphinx-quickstart doesn't accept non-ASCII character as a option argument. +* #1773: sphinx-quickstart doesn't accept non-ASCII character as a option + argument. * #1766: the message "least Python 2.6 to run" is at best misleading. * #1772: cross reference in docstrings like ``:param .write:`` breaks building. * #1770, #1774: ``literalinclude`` with empty file occurs exception. Thanks to @@ -2993,10 +3109,11 @@ Bugs fixed begin with -, / or +. Thanks to Takayuki Hirai. * #1753: C++, added missing support for more complex declarations. * #1700: Add ``:caption:`` option for :rst:dir:`toctree`. -* #1742: ``:name:`` option is provided for :rst:dir:`toctree`, :rst:dir:`code-block` and - :rst:dir:`literalinclude` directives. +* #1742: ``:name:`` option is provided for :rst:dir:`toctree`, + :rst:dir:`code-block` and :rst:dir:`literalinclude` directives. * #1756: Incorrect section titles in search that was introduced from 1.3b3. -* #1746: C++, fixed name lookup procedure, and added missing lookups in declarations. +* #1746: C++, fixed name lookup procedure, and added missing lookups in + declarations. * #1765: C++, fix old id generation to use fully qualified names. Documentation @@ -3063,14 +3180,16 @@ Bugs fixed * #1690: toctrees with ``glob`` option now can also contain entries for single documents with explicit title. * #1591: html search results for C++ elements now has correct interpage links. -* bizstyle theme: nested long title pages make long breadcrumb that breaks page layout. +* bizstyle theme: nested long title pages make long breadcrumb that breaks page + layout. * bizstyle theme: all breadcrumb items become 'Top' on some mobile browser (iPhone5s safari). -* #1722: restore ``toctree()`` template function behavior that was changed at 1.3b1. +* #1722: restore ``toctree()`` template function behavior that was changed at + 1.3b1. * #1732: i18n: localized table caption raises exception. * #1718: ``:numref:`` does not work with capital letters in the label -* #1630: resolve CSS conflicts, ``div.container`` css target for literal block wrapper - now renamed to ``div.literal-block-wrapper``. +* #1630: resolve CSS conflicts, ``div.container`` css target for literal block + wrapper now renamed to ``div.literal-block-wrapper``. * ``sphinx.util.pycompat`` has been restored in its backwards-compatibility; slated for removal in Sphinx 1.4. * #1719: LaTeX writer does not respect ``numref_format`` option in captions @@ -3304,8 +3423,8 @@ Release 1.2.3 (released Sep 1, 2014) Features added -------------- -* #1518: ``sphinx-apidoc`` command now has a ``--version`` option to show version - information and exit +* #1518: ``sphinx-apidoc`` command now has a ``--version`` option to show + version information and exit * New locales: Hebrew, European Portuguese, Vietnamese. Bugs fixed @@ -3647,17 +3766,17 @@ Features added template function has been fixed (bug #1046). - PR#99: Strip down seealso directives to normal admonitions. This removes their unusual CSS classes (admonition-see-also), inconsistent LaTeX - admonition title ("See Also" instead of "See also"), and spurious indentation - in the text builder. + admonition title ("See Also" instead of "See also"), and spurious + indentation in the text builder. * HTML builder - #783: Create a link to full size image if it is scaled with width or height. - - #1067: Improve the ordering of the JavaScript search results: matches in titles - come before matches in full text, and object results are better categorized. - Also implement a pluggable search scorer. - - #1053: The "rightsidebar" and "collapsiblesidebar" HTML theme options now work - together. + - #1067: Improve the ordering of the JavaScript search results: matches in + titles come before matches in full text, and object results are better + categorized. Also implement a pluggable search scorer. + - #1053: The "rightsidebar" and "collapsiblesidebar" HTML theme options now + work together. - Update to jQuery 1.7.1 and Underscore.js 1.3.1. * Texinfo builder @@ -4355,8 +4474,8 @@ Features added * General: - Added a "nitpicky" mode that emits warnings for all missing - references. It is activated by the :option:`sphinx-build -n` command-line switch - or the `nitpicky` config value. + references. It is activated by the :option:`sphinx-build -n` command-line + switch or the `nitpicky` config value. - Added ``latexpdf`` target in quickstart Makefile. * Markup: diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 1ca1fc608c..1807d3998c 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -303,8 +303,8 @@ Debugging Tips * Set the debugging options in the `Docutils configuration file `_. -* JavaScript stemming algorithms in ``sphinx/search/*.py`` (except ``en.py``) are - generated by this +* JavaScript stemming algorithms in ``sphinx/search/*.py`` (except ``en.py``) + are generated by this `modified snowballcode generator `_. Generated `JSX `_ files are in `this repository `_. diff --git a/Makefile b/Makefile index 89b5bb5aae..542083c494 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,10 @@ style-check: type-check: mypy sphinx +.PHONY: doclinter +doclinter: + python utils/doclinter.py CHANGES *.rst doc/ + .PHONY: pylint pylint: @pylint --rcfile utils/pylintrc sphinx diff --git a/doc/develop.rst b/doc/develop.rst index 3828b709de..0612c7113a 100644 --- a/doc/develop.rst +++ b/doc/develop.rst @@ -46,7 +46,8 @@ This is the current list of contributed extensions in that repository: - coffeedomain: a domain for (auto)documenting CoffeeScript source code - context: a builder for ConTeXt - disqus: embed Disqus comments in documents -- documentedlist: converts a Python list to a table in the generated documentation +- documentedlist: converts a Python list to a table in the generated + documentation - doxylink: Link to external Doxygen-generated HTML documentation - domaintools_: A tool for easy domain creation - email: obfuscate email addresses @@ -76,7 +77,8 @@ This is the current list of contributed extensions in that repository: - nicovideo: embed videos from nicovideo - nwdiag: embed network diagrams by using nwdiag_ - omegat: support tools to collaborate with OmegaT_ (Sphinx 1.1 needed) -- osaka: convert standard Japanese doc to Osaka dialect (this is a joke extension) +- osaka: convert standard Japanese doc to Osaka dialect (this is a joke + extension) - paverutils: an alternate integration of Sphinx with Paver_ - phpdomain: an extension for PHP support - plantuml: embed UML diagram by using PlantUML_ @@ -96,7 +98,8 @@ This is the current list of contributed extensions in that repository: - sword: an extension inserting Bible verses from Sword_ - tikz: draw pictures with the `TikZ/PGF LaTeX package`_ - traclinks: create TracLinks_ to a Trac_ instance from within Sphinx -- versioning: Sphinx extension that allows building versioned docs for self-hosting +- versioning: Sphinx extension that allows building versioned docs for + self-hosting - whooshindex: whoosh indexer extension - youtube: embed videos from YouTube_ - zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_ diff --git a/doc/development/tutorials/helloworld.rst b/doc/development/tutorials/helloworld.rst index a042f7b05d..6eae5d6a3a 100644 --- a/doc/development/tutorials/helloworld.rst +++ b/doc/development/tutorials/helloworld.rst @@ -77,7 +77,7 @@ create directives should extend this class. .. seealso:: - `The docutils documentation on creating directives `_ + `The docutils documentation on creating directives `_ This class contains a ``run`` method. This method is a requirement and it is part of every directive. It contains the main logic of the directive and it @@ -87,7 +87,7 @@ nodes available: text, paragraph, reference, table, etc. .. seealso:: - `The docutils documentation on nodes `_ + `The docutils documentation on nodes `_ The ``nodes.paragraph`` class creates a new paragraph node. A paragraph node typically contains some text that we can set during instantiation using diff --git a/doc/development/tutorials/todo.rst b/doc/development/tutorials/todo.rst index 78a37c2fe1..f4ac85ac94 100644 --- a/doc/development/tutorials/todo.rst +++ b/doc/development/tutorials/todo.rst @@ -23,8 +23,8 @@ We want the extension to add the following to Sphinx: only shown in the output if a new config value is set. Todo entries should not be in the output by default. -* A ``todolist`` directive that creates a list of all todo entries throughout the - documentation. +* A ``todolist`` directive that creates a list of all todo entries throughout + the documentation. For that, we will need to add the following elements to Sphinx: diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 18eea34e7b..46540595f7 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -145,9 +145,9 @@ Sphinx core events ------------------ These events are known to the core. The arguments shown are given to the -registered event handlers. Use :meth:`.Sphinx.connect` in an extension's ``setup`` -function (note that ``conf.py`` can also have a ``setup`` function) to connect -handlers to the events. Example: +registered event handlers. Use :meth:`.Sphinx.connect` in an extension's +``setup`` function (note that ``conf.py`` can also have a ``setup`` function) to +connect handlers to the events. Example: .. code-block:: python diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 2ecb1e2e79..38fae288c1 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -171,6 +171,11 @@ The following is a list of deprecated interfaces. - 4.0 - N/A + * - ``sphinx.ext.apidoc.makename()`` + - 2.1 + - 4.0 + - ``sphinx.ext.apidoc.module_join()`` + * - ``sphinx.ext.autodoc.importer.MockFinder`` - 2.1 - 4.0 @@ -1066,7 +1071,9 @@ The following is a list of deprecated interfaces. * - ``sphinx.websupport`` - 1.6 - 2.0 - - `sphinxcontrib-websupport `_ + - `sphinxcontrib-websupport`_ + + .. _sphinxcontrib-websupport: https://pypi.org/project/sphinxcontrib-websupport/ * - ``StandaloneHTMLBuilder.css_files`` - 1.6 diff --git a/doc/extdev/i18n.rst b/doc/extdev/i18n.rst index c3ec173a26..a3232b8576 100644 --- a/doc/extdev/i18n.rst +++ b/doc/extdev/i18n.rst @@ -19,7 +19,7 @@ i18n API .. _ext-i18n: Extension internationalization (`i18n`) and localization (`l10n`) using i18n API ---------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- .. versionadded:: 1.8 diff --git a/doc/extdev/index.rst b/doc/extdev/index.rst index c70ca37be2..8c909e3150 100644 --- a/doc/extdev/index.rst +++ b/doc/extdev/index.rst @@ -144,9 +144,9 @@ in which a Sphinx project is built: this works in several phases. Now that the metadata and cross-reference data of all existing documents is known, all temporary nodes are replaced by nodes that can be converted into - output using components called transforms. For example, links are created for - object references that exist, and simple literal nodes are created for those - that don't. + output using components called transforms. For example, links are created + for object references that exist, and simple literal nodes are created for + those that don't. **Phase 4: Writing** diff --git a/doc/extdev/logging.rst b/doc/extdev/logging.rst index b66f11dbb4..e6c4dc66dc 100644 --- a/doc/extdev/logging.rst +++ b/doc/extdev/logging.rst @@ -56,8 +56,8 @@ Logging API :meth:`SphinxLoggerAdapter.warning`. **color** - The color of logs. By default, info and verbose level logs are not colored, - and debug level ones are colored as ``"darkgray"``. + The color of logs. By default, info and verbose level logs are not + colored, and debug level ones are colored as ``"darkgray"``. .. autofunction:: pending_logging() diff --git a/doc/extdev/markupapi.rst b/doc/extdev/markupapi.rst index fc25c23279..7a21f81268 100644 --- a/doc/extdev/markupapi.rst +++ b/doc/extdev/markupapi.rst @@ -138,8 +138,8 @@ Both APIs parse the content into a given node. They are used like this:: .. deprecated:: 1.7 - Until Sphinx-1.6, ``sphinx.ext.autodoc.AutodocReporter`` is used for this purpose. - For now, it is replaced by ``switch_source_input()``. + Until Sphinx-1.6, ``sphinx.ext.autodoc.AutodocReporter`` is used for this + purpose. For now, it is replaced by ``switch_source_input()``. If you don't need the wrapping node, you can use any concrete node type and return ``node.children`` from the Directive. diff --git a/doc/faq.rst b/doc/faq.rst index cd5eb26c80..acd2ac16f0 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -37,9 +37,6 @@ How do I... You'll still need to mark up classes and such, but the headings and code examples come through cleanly. -... create HTML slides from Sphinx documents? - See the "Hieroglyph" package at https://github.com/nyergler/hieroglyph. - For many more extensions and other contributed stuff, see the sphinx-contrib_ repository. @@ -51,12 +48,10 @@ Using Sphinx with... -------------------- Read the Docs - `Read the Docs `_ is a documentation hosting service based around - Sphinx. They will host sphinx documentation, along with supporting a number - of other features including version support, PDF generation, and more. The - `Getting Started - `_ - guide is a good place to start. + `Read the Docs `_ is a documentation hosting + service based around Sphinx. They will host sphinx documentation, along + with supporting a number of other features including version support, PDF + generation, and more. The `Getting Started`_ guide is a good place to start. Epydoc There's a third-party extension providing an `api role`_ which refers to @@ -83,7 +78,8 @@ GitHub Pages Sphinx HTML output properly. MediaWiki - See https://bitbucket.org/kevindunn/sphinx-wiki/wiki/Home, a project by Kevin Dunn. + See https://bitbucket.org/kevindunn/sphinx-wiki/wiki/Home, a project by + Kevin Dunn. Google Analytics You can use a custom ``layout.html`` template, like this: @@ -149,6 +145,7 @@ Google Search 3. Add ``searchbox.html`` to the :confval:`html_sidebars` configuration value. +.. _Getting Started: https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html .. _api role: https://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py .. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py diff --git a/doc/intro.rst b/doc/intro.rst index 622d16b834..f6f6218bda 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -17,10 +17,10 @@ docs have a look at `Epydoc `_, which also understands reST. For a great "introduction" to writing docs in general -- the whys and hows, see -also `Write the docs `_, written by Eric -Holscher. +also `Write the docs`_, written by Eric Holscher. .. _rinohtype: https://github.com/brechtm/rinohtype +.. _Write the docs: http://www.writethedocs.org/guide/writing/beginners-guide-to-docs/ Conversion from other systems ----------------------------- diff --git a/doc/man/sphinx-apidoc.rst b/doc/man/sphinx-apidoc.rst index 384374aa94..aef497e0d4 100644 --- a/doc/man/sphinx-apidoc.rst +++ b/doc/man/sphinx-apidoc.rst @@ -4,7 +4,8 @@ sphinx-apidoc Synopsis -------- -**sphinx-apidoc** [*OPTIONS*] -o <*OUTPUT_PATH*> <*MODULE_PATH*> [*EXCLUDE_PATTERN*, ...] +**sphinx-apidoc** [*OPTIONS*] -o <*OUTPUT_PATH*> <*MODULE_PATH*> +[*EXCLUDE_PATTERN*, ...] Description ----------- diff --git a/doc/man/sphinx-build.rst b/doc/man/sphinx-build.rst index 5ec53cf7f1..1ef0e07dc3 100644 --- a/doc/man/sphinx-build.rst +++ b/doc/man/sphinx-build.rst @@ -302,7 +302,8 @@ variables to customize behavior: .. describe:: SPHINXOPTS - Additional options for :program:`sphinx-build`. + Additional options for :program:`sphinx-build`. These options can + also be set via the shortcut variable **O** (capital 'o'). .. _when-deprecation-warnings-are-displayed: diff --git a/doc/templating.rst b/doc/templating.rst index 3790275f5e..14fb31ed89 100644 --- a/doc/templating.rst +++ b/doc/templating.rst @@ -297,7 +297,8 @@ in the future. The "page name" of the current file, i.e. either the document name if the file is generated from a reST source, or the equivalent hierarchical name - relative to the output directory (``[directory/]filename_without_extension``). + relative to the output directory + (``[directory/]filename_without_extension``). .. data:: project diff --git a/doc/theming.rst b/doc/theming.rst index 4d4af4d90b..e2ef1fcf2a 100644 --- a/doc/theming.rst +++ b/doc/theming.rst @@ -49,8 +49,9 @@ Python :mod:`ConfigParser` module) and has the following structure: * The **inherit** setting gives the name of a "base theme", or ``none``. The base theme will be used to locate missing templates (most themes will not have to supply most templates if they use ``basic`` as the base theme), its options - will be inherited, and all of its static files will be used as well. If you want - to also inherit the stylesheet, include it via CSS' ``@import`` in your own. + will be inherited, and all of its static files will be used as well. If you + want to also inherit the stylesheet, include it via CSS' ``@import`` in your + own. * The **stylesheet** setting gives the name of a CSS file which will be referenced in the HTML header. If you need more than one CSS file, either diff --git a/doc/usage/advanced/websupport/quickstart.rst b/doc/usage/advanced/websupport/quickstart.rst index de76922316..a550803392 100644 --- a/doc/usage/advanced/websupport/quickstart.rst +++ b/doc/usage/advanced/websupport/quickstart.rst @@ -63,7 +63,7 @@ This dict can then be used as context for templates. The goal is to be easy to integrate with your existing templating system. An example using `Jinja2 `_ is: -.. sourcecode:: html+jinja +.. code-block:: html+jinja {%- extends "layout.html" %} diff --git a/doc/usage/builders/index.rst b/doc/usage/builders/index.rst index 3b74a02e17..db6706944f 100644 --- a/doc/usage/builders/index.rst +++ b/doc/usage/builders/index.rst @@ -61,7 +61,7 @@ The builder's "name" must be given to the **-b** command-line option of .. versionadded:: 1.0 -.. module:: sphinx.builders.htmlhelp +.. module:: sphinxcontrib.htmlhelp .. class:: HTMLHelpBuilder This builder produces the same output as the standalone HTML builder, but diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst index 31a9e0d1cb..f411abb1c7 100644 --- a/doc/usage/configuration.rst +++ b/doc/usage/configuration.rst @@ -296,25 +296,26 @@ General configuration Sphinx supports following warning types: - * app.add_node - * app.add_directive - * app.add_role - * app.add_generic_role - * app.add_source_parser - * download.not_readable - * image.not_readable - * ref.term - * ref.ref - * ref.numref - * ref.keyword - * ref.option - * ref.citation - * ref.footnote - * ref.doc - * ref.python - * misc.highlighting_failure - * toc.secnum - * epub.unknown_project_files + * ``app.add_node`` + * ``app.add_directive`` + * ``app.add_role`` + * ``app.add_generic_role`` + * ``app.add_source_parser`` + * ``download.not_readable`` + * ``image.not_readable`` + * ``ref.term`` + * ``ref.ref`` + * ``ref.numref`` + * ``ref.keyword`` + * ``ref.option`` + * ``ref.citation`` + * ``ref.footnote`` + * ``ref.doc`` + * ``ref.python`` + * ``misc.highlighting_failure`` + * ``toc.secnum`` + * ``epub.unknown_project_files`` + * ``autosectionlabel.*`` You can choose from these types. @@ -334,6 +335,10 @@ General configuration Added ``ref.footnote`` + .. versionchanged:: 2.1 + + Added ``autosectionlabel.*`` + .. confval:: needs_sphinx If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will diff --git a/doc/usage/extensions/autodoc.rst b/doc/usage/extensions/autodoc.rst index 0b6061e783..8fdee214b7 100644 --- a/doc/usage/extensions/autodoc.rst +++ b/doc/usage/extensions/autodoc.rst @@ -40,10 +40,8 @@ you can also enable the :mod:`napoleon ` extension. :mod:`napoleon ` is a preprocessor that converts your docstrings to correct reStructuredText before :mod:`autodoc` processes them. -.. _Google: - https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings -.. _NumPy: - https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt +.. _Google: https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings +.. _NumPy: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt Directives @@ -431,6 +429,16 @@ There are also config values that you can set: This config value only requires to declare the top-level modules that should be mocked. +.. confval:: autodoc_typehints + + This value controls how to represents typehints. The setting takes the + following values: + + * ``'signature'`` -- Show typehints as its signature (default) + * ``'none'`` -- Do not show typehints + + .. versionadded: 2.1 + .. confval:: autodoc_warningiserror This value controls the behavior of :option:`sphinx-build -W` during diff --git a/doc/usage/extensions/coverage.rst b/doc/usage/extensions/coverage.rst index 1fb9b1850b..46d31053ca 100644 --- a/doc/usage/extensions/coverage.rst +++ b/doc/usage/extensions/coverage.rst @@ -22,6 +22,16 @@ should check: .. confval:: coverage_ignore_classes +.. confval:: coverage_ignore_pyobjects + + List of `Python regular expressions`_. + + If any of these regular expressions matches any part of the full import path + of a Python object, that Python object is excluded from the documentation + coverage report. + + .. versionadded:: 2.1 + .. confval:: coverage_c_path .. confval:: coverage_c_regexes @@ -40,3 +50,5 @@ should check: ``False`` by default. .. versionadded:: 1.1 + +.. _Python regular expressions: https://docs.python.org/library/re \ No newline at end of file diff --git a/doc/usage/extensions/graphviz.rst b/doc/usage/extensions/graphviz.rst index bb50465ad3..4d801d3460 100644 --- a/doc/usage/extensions/graphviz.rst +++ b/doc/usage/extensions/graphviz.rst @@ -84,8 +84,8 @@ It adds these directives: ``dot`` command within the directive. .. versionadded:: 1.5 - All three directives support a ``align`` option to align the graph horizontal. - The values "left", "center", "right" are allowed. + All three directives support a ``align`` option to align the graph + horizontal. The values "left", "center", "right" are allowed. .. versionadded:: 1.6 All three directives support a ``name`` option to set the label to graph. diff --git a/doc/usage/extensions/ifconfig.rst b/doc/usage/extensions/ifconfig.rst index 2bd9d0e3b3..837c0b35a8 100644 --- a/doc/usage/extensions/ifconfig.rst +++ b/doc/usage/extensions/ifconfig.rst @@ -33,6 +33,6 @@ This extension is quite simple, and features only one directive: def setup(app): app.add_config_value('releaselevel', '', 'env') - The second argument is the default value, the third should always be ``'env'`` - for such values (it selects if Sphinx re-reads the documents if the value - changes). + The second argument is the default value, the third should always be + ``'env'`` for such values (it selects if Sphinx re-reads the documents if the + value changes). diff --git a/doc/usage/extensions/inheritance.rst b/doc/usage/extensions/inheritance.rst index 8e98b0bc13..78895915b7 100644 --- a/doc/usage/extensions/inheritance.rst +++ b/doc/usage/extensions/inheritance.rst @@ -36,8 +36,8 @@ It adds this directive: with ``lib.``, you can give ``:parts: -1`` to remove that prefix from the displayed node names. - The directive also supports a ``private-bases`` flag option; if given, private base - classes (those whose name starts with ``_``) will be included. + The directive also supports a ``private-bases`` flag option; if given, + private base classes (those whose name starts with ``_``) will be included. You can use ``caption`` option to give a caption to the diagram. diff --git a/doc/usage/extensions/todo.rst b/doc/usage/extensions/todo.rst index 982005bd65..bf8b922251 100644 --- a/doc/usage/extensions/todo.rst +++ b/doc/usage/extensions/todo.rst @@ -17,8 +17,9 @@ There are two additional directives when using this extension: ``True``. .. versionadded:: 1.3.2 - This directive supports an ``class`` option that determines the class attribute - for HTML output. If not given, the class defaults to ``admonition-todo``. + This directive supports an ``class`` option that determines the class + attribute for HTML output. If not given, the class defaults to + ``admonition-todo``. .. rst:directive:: todolist @@ -46,8 +47,8 @@ Configuration .. confval:: todo_link_only - If this is ``True``, :rst:dir:`todolist` produce output without file path and line, - The default is ``False``. + If this is ``True``, :rst:dir:`todolist` produce output without file path and + line, The default is ``False``. .. versionadded:: 1.4 @@ -57,5 +58,5 @@ autodoc provides the following an additional event: .. versionadded:: 1.5 - Emitted when a todo is defined. *node* is the defined ``sphinx.ext.todo.todo_node`` - node. + Emitted when a todo is defined. *node* is the defined + ``sphinx.ext.todo.todo_node`` node. diff --git a/doc/usage/quickstart.rst b/doc/usage/quickstart.rst index 5279d3f87f..8566552e05 100644 --- a/doc/usage/quickstart.rst +++ b/doc/usage/quickstart.rst @@ -6,7 +6,7 @@ Once Sphinx is :doc:`installed `, you can proceed with setting up your first Sphinx project. To ease the process of getting started, Sphinx provides a tool, :program:`sphinx-quickstart`, which will generate a documentation source directory and populate it with some defaults. We're going -to use the :program:`sphinx-quickstart` tool here, though it's use by no means +to use the :program:`sphinx-quickstart` tool here, though its use is by no means necessary. @@ -26,7 +26,7 @@ configuration values from a few questions it asks you. To use this, run: $ sphinx-quickstart -Answer each question asked. Be sure to say yes to the ``autodoc`` extension, as +Answer each question asked. Be sure to say "yes" to the ``autodoc`` extension, as we will use this later. There is also an automatic "API documentation" generator called @@ -103,7 +103,7 @@ In Sphinx source files, you can use most features of standard For example, you can add cross-file references in a portable way (which works for all output types) using the :rst:role:`ref` role. -For an example, if you are viewing the HTML version you can look at the source +For an example, if you are viewing the HTML version, you can look at the source for this document -- use the "Show Source" link in the sidebar. .. todo:: Update the below link when we add new guides on these. diff --git a/doc/usage/restructuredtext/directives.rst b/doc/usage/restructuredtext/directives.rst index 85ee22ae99..d00979255a 100644 --- a/doc/usage/restructuredtext/directives.rst +++ b/doc/usage/restructuredtext/directives.rst @@ -686,8 +686,8 @@ Glossary (When the glossary is sorted, the first term determines the sort order.) - If you want to specify "grouping key" for general index entries, you can put a "key" - as "term : key". For example:: + If you want to specify "grouping key" for general index entries, you can put + a "key" as "term : key". For example:: .. glossary:: @@ -697,12 +697,12 @@ Glossary Note that "key" is used for grouping key as is. The "key" isn't normalized; key "A" and "a" become different groups. - The whole characters in "key" is used instead of a first character; it is used for - "Combining Character Sequence" and "Surrogate Pairs" grouping key. + The whole characters in "key" is used instead of a first character; it is + used for "Combining Character Sequence" and "Surrogate Pairs" grouping key. - In i18n situation, you can specify "localized term : key" even if original text only - have "term" part. In this case, translated "localized term" will be categorized in - "key" group. + In i18n situation, you can specify "localized term : key" even if original + text only have "term" part. In this case, translated "localized term" will be + categorized in "key" group. .. versionadded:: 0.6 You can now give the glossary directive a ``:sorted:`` flag that will @@ -958,16 +958,16 @@ this reason, the following directive exists: .. warning:: Tables with more than 30 rows are rendered using ``longtable``, not - ``tabulary``, in order to allow pagebreaks. The ``L``, ``R``, ... specifiers - do not work for these tables. + ``tabulary``, in order to allow pagebreaks. The ``L``, ``R``, ... + specifiers do not work for these tables. Tables that contain list-like elements such as object descriptions, blockquotes or any kind of lists cannot be set out of the box with - ``tabulary``. They are therefore set with the standard LaTeX ``tabular`` (or - ``longtable``) environment if you don't give a ``tabularcolumns`` directive. - If you do, the table will be set with ``tabulary`` but you must use the - ``p{width}`` construct (or Sphinx's ``\X`` and ``\Y`` specifiers described - below) for the columns containing these elements. + ``tabulary``. They are therefore set with the standard LaTeX ``tabular`` + (or ``longtable``) environment if you don't give a ``tabularcolumns`` + directive. If you do, the table will be set with ``tabulary`` but you + must use the ``p{width}`` construct (or Sphinx's ``\X`` and ``\Y`` + specifiers described below) for the columns containing these elements. Literal blocks do not work with ``tabulary`` at all, so tables containing a literal block are always set with ``tabular``. The verbatim environment @@ -996,10 +996,11 @@ this reason, the following directive exists: .. versionchanged:: 1.6 Merged cells from complex grid tables (either multi-row, multi-column, or - both) now allow blockquotes, lists, literal blocks, ... as do regular cells. + both) now allow blockquotes, lists, literal blocks, ... as do regular + cells. - Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``, ``Y{f}`` - and tabulary's columns. + Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``, + ``Y{f}`` and tabulary's columns. .. note:: diff --git a/doc/usage/restructuredtext/domains.rst b/doc/usage/restructuredtext/domains.rst index 8b06bf0e03..6f79f8c17e 100644 --- a/doc/usage/restructuredtext/domains.rst +++ b/doc/usage/restructuredtext/domains.rst @@ -128,17 +128,28 @@ declarations: This directive will also cause an entry in the global module index. - The ``platform`` option, if present, is a comma-separated list of the - platforms on which the module is available (if it is available on all - platforms, the option should be omitted). The keys are short identifiers; - examples that are in use include "IRIX", "Mac", "Windows", and "Unix". It is - important to use a key which has already been used when applicable. + .. rubric:: options - The ``synopsis`` option should consist of one sentence describing the - module's purpose -- it is currently only used in the Global Module Index. + .. rst:directive:option:: platform: platforms + :type: comma separated list - The ``deprecated`` option can be given (with no value) to mark a module as - deprecated; it will be designated as such in various locations then. + Indicate platforms which the module is available (if it is available on + all platforms, the option should be omitted). The keys are short + identifiers; examples that are in use include "IRIX", "Mac", "Windows" + and "Unix". It is important to use a key which has already been used when + applicable. + + .. rst:directive:option:: synopsis: purpose + :type: text + + Consist of one sentence describing the module's purpose -- it is currently + only used in the Global Module Index. + + .. rst:directive:option:: deprecated + :type: no argument + + Mark a module as deprecated; it will be designated as such in various + locations then. .. rst:directive:: .. py:currentmodule:: name @@ -169,12 +180,14 @@ The following directives are provided for module and class contents: This information can (in any ``py`` directive) optionally be given in a structured form, see :ref:`info-field-lists`. - The ``async`` option can be given (with no value) to indicate the function is - an async method. + .. rubric:: options - .. versionchanged:: 2.1 + .. rst:directive:option:: async + :type: no value - ``:async:`` option added. + Indicate the function is an async function. + + .. versionadded:: 2.1 .. rst:directive:: .. py:data:: name @@ -223,19 +236,43 @@ The following directives are provided for module and class contents: described for ``function``. See also :ref:`signatures` and :ref:`info-field-lists`. - The ``async`` option can be given (with no value) to indicate the method is - an async method. + .. rubric:: options - The ``classmethod`` option and ``staticmethod`` option can be given (with - no value) to indicate the method is a class method (or a static method). + .. rst:directive:option:: abstractmethod + :type: no value - The ``property`` option can be given (with no value) to indicate the method - is a property. + Indicate the method is an abstract method. - .. versionchanged:: 2.1 + .. versionadded:: 2.1 + + .. rst:directive:option:: async + :type: no value + + Indicate the method is an async method. + + .. versionadded:: 2.1 + + .. rst:directive:option:: classmethod + :type: no value + + Indicate the method is a class method. + + .. versionadded:: 2.1 + + .. rst:directive:option:: property + :type: no value + + Indicate the method is a property. + + .. versionadded:: 2.1 + + .. rst:directive:option:: staticmethod + :type: no value + + Indicate the method is a static method. + + .. versionadded:: 2.1 - ``:async:``, ``:classmethod:``, ``:property:`` and ``:staticmethod:`` - options added. .. rst:directive:: .. py:staticmethod:: name(parameters) @@ -720,7 +757,8 @@ visibility statement (``public``, ``private`` or ``protected``). .. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type::type - A scoped enum with non-default visibility, and with a specified underlying type. + A scoped enum with non-default visibility, and with a specified + underlying type. .. rst:directive:: .. cpp:enumerator:: name .. cpp:enumerator:: name = constant @@ -760,7 +798,8 @@ visibility statement (``public``, ``private`` or ``protected``). **Valid Expressions** - :cpp:expr:`*r`, when :cpp:expr:`r` is dereferenceable. - - :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when :cpp:expr:`r` is incrementable. + - :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when + :cpp:expr:`r` is incrementable. This will render as follows: @@ -799,11 +838,12 @@ Anonymous Entities ~~~~~~~~~~~~~~~~~~ C++ supports anonymous namespaces, classes, enums, and unions. -For the sake of documentation they must be given some name that starts with ``@``, -e.g., ``@42`` or ``@data``. +For the sake of documentation they must be given some name that starts with +``@``, e.g., ``@42`` or ``@data``. These names can also be used in cross-references and (type) expressions, though nested symbols will be found even when omitted. -The ``@...`` name will always be rendered as **[anonymous]** (possibly as a link). +The ``@...`` name will always be rendered as **[anonymous]** (possibly as a +link). Example:: @@ -835,8 +875,8 @@ Explicit ref: :cpp:var:`Data::@data::a`. Short-hand ref: :cpp:var:`Data::a`. Aliasing Declarations ~~~~~~~~~~~~~~~~~~~~~ -Sometimes it may be helpful list declarations elsewhere than their main documentation, -e.g., when creating a synopsis of a class interface. +Sometimes it may be helpful list declarations elsewhere than their main +documentation, e.g., when creating a synopsis of a class interface. The following directive can be used for this purpose. .. rst:directive:: .. cpp:alias:: name or function signature @@ -1079,7 +1119,8 @@ These roles link to the given declaration types: be properly qualified relative to the position of the link. .. versionadded:: 2.0 - The :rst:role:`cpp:struct` role as alias for the :rst:role:`cpp:class` role. + The :rst:role:`cpp:struct` role as alias for the :rst:role:`cpp:class` + role. .. admonition:: Note on References with Templates Parameters/Arguments @@ -1126,7 +1167,8 @@ References using the :rst:role:`cpp:func` role: - Specific overload: ``void C::f()``, :cpp:func:`void C::f()` - Specific overload: ``void C::f(int)``, :cpp:func:`void C::f(int)` - Specific overload: ``void C::f(double)``, :cpp:func:`void C::f(double)` -- Specific overload: ``void C::f(double) const``, :cpp:func:`void C::f(double) const` +- Specific overload: ``void C::f(double) const``, + :cpp:func:`void C::f(double) const` Note that the :confval:`add_function_parentheses` configuration variable does not influence specific overload references. @@ -1155,8 +1197,9 @@ and template arguments for the prefix of qualified names. For example: - ``template\ template\ Wrapper::Outer::Inner`` (:cpp:class:`template\ template\ Wrapper::Outer::Inner`) -Currently the lookup only succeed if the template parameter identifiers are equal strings. -That is, ``template\ Wrapper::Outer`` will not work. +Currently the lookup only succeed if the template parameter identifiers are +equal strings. That is, ``template\ Wrapper::Outer`` will not +work. As a shorthand notation, if a template parameter list is omitted, then the lookup will assume either a primary template or a non-template, @@ -1447,8 +1490,8 @@ The reStructuredText domain (name **rst**) provides the following directives: .. rubric:: options - .. rst:directive:option:: type - :type: description for the option of directive + .. rst:directive:option:: type: description of argument + :type: text Describe the type of option value. @@ -1459,7 +1502,7 @@ The reStructuredText domain (name **rst**) provides the following directives: .. rst:directive:option:: maxdepth :type: integer or no value - .. versionadded:: 2.1 + .. versionadded:: 2.1 .. rst:directive:: .. rst:role:: name diff --git a/sphinx/application.py b/sphinx/application.py index e9b950c83f..411fa42d86 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -343,9 +343,16 @@ class Sphinx: status = (self.statuscode == 0 and __('succeeded') or __('finished with problems')) if self._warncount: - logger.info(bold(__('build %s, %s warning.', - 'build %s, %s warnings.', self._warncount) % - (status, self._warncount))) + if self.warningiserror: + msg = __('build %s, %s warning (with warnings treated as errors).', + 'build %s, %s warnings (with warnings treated as errors).', + self._warncount) + else: + msg = __('build %s, %s warning.', + 'build %s, %s warnings.', + self._warncount) + + logger.info(bold(msg % (status, self._warncount))) else: logger.info(bold(__('build %s.') % status)) diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index 973e7c67d9..e5754ec9b2 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -180,12 +180,10 @@ class LaTeXBuilder(Builder): # Add special settings for latex_engine self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {})) - # for xelatex+French, don't use polyglossia by default - if self.config.latex_engine == 'xelatex': - if self.config.language: - if self.config.language[:2] == 'fr': - self.context['polyglossia'] = '' - self.context['babel'] = r'\usepackage{babel}' + # Add special settings for (latex_engine, language_code) + if self.config.language: + key = (self.config.latex_engine, self.config.language[:2]) + self.context.update(ADDITIONAL_SETTINGS.get(key, {})) # Apply extension settings to context self.context['packages'] = self.usepackages @@ -441,6 +439,8 @@ def default_latex_engine(config): """ Better default latex_engine settings for specific languages. """ if config.language == 'ja': return 'platex' + elif (config.language or '').startswith('zh'): + return 'xelatex' else: return 'pdflatex' diff --git a/sphinx/builders/latex/util.py b/sphinx/builders/latex/util.py index 1765cb0ce1..117e82e087 100644 --- a/sphinx/builders/latex/util.py +++ b/sphinx/builders/latex/util.py @@ -36,11 +36,13 @@ class ExtBabel(Babel): # polyglossia calls new orthography (Neue Rechtschreibung) as # german (with new spelling option). return 'german' - elif not language: + elif language: + return language + elif language_code.startswith('zh'): + return 'english' # fallback to english (behaves like supported) + else: self.supported = False return 'english' # fallback to english - else: - return language def get_mainlanguage_options(self): # type: () -> str diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 84a69436ae..164f1e6b7e 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -108,7 +108,8 @@ class CheckExternalLinksBuilder(Builder): kwargs = { 'allow_redirects': True, 'headers': { - 'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8' + 'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8', + 'User-Agent': requests.useragent_header[0][1], }, } if self.app.config.linkcheck_timeout: diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 4bfaaf8481..f5bb3000c0 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -576,6 +576,7 @@ class PyMethod(PyObject): option_spec = PyObject.option_spec.copy() option_spec.update({ + 'abstractmethod': directives.flag, 'async': directives.flag, 'classmethod': directives.flag, 'property': directives.flag, @@ -592,6 +593,8 @@ class PyMethod(PyObject): def get_signature_prefix(self, sig): # type: (str) -> str prefix = [] + if 'abstractmethod' in self.options: + prefix.append('abstract') if 'async' in self.options: prefix.append('async') if 'classmethod' in self.options: @@ -849,7 +852,6 @@ class PythonModuleIndex(Index): last = entries[-1] entries[-1] = IndexEntry(last[0], 1, last[2], last[3], last[4], last[5], last[6]) - entries.append(IndexEntry(stripped + package, 1, '', '', '', '', '')) elif not prev_modname.startswith(package): # submodule without parent in list, add dummy entry entries.append(IndexEntry(stripped + package, 1, '', '', '', '', '')) diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index f054abf286..3490432945 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -139,6 +139,7 @@ class ReSTDirectiveOption(ReSTMarkup): def add_target_and_index(self, name, sig, signode): # type: (str, str, addnodes.desc_signature) -> None + directive_name = self.current_directive targetname = '-'.join([self.objtype, self.current_directive, name]) if targetname not in self.state.document.ids: signode['names'].append(targetname) @@ -146,12 +147,13 @@ class ReSTDirectiveOption(ReSTMarkup): signode['first'] = (not self.names) self.state.document.note_explicit_target(signode) + objname = ':'.join(filter(None, [directive_name, name])) domain = cast(ReSTDomain, self.env.get_domain('rst')) - domain.note_object(self.objtype, name, location=(self.env.docname, self.lineno)) + domain.note_object(self.objtype, objname, location=(self.env.docname, self.lineno)) - if self.current_directive: + if directive_name: key = name[0].upper() - pair = [_('%s (directive)') % self.current_directive, + pair = [_('%s (directive)') % directive_name, _(':%s: (directive option)') % name] self.indexnode['entries'].append(('pair', '; '.join(pair), targetname, '', key)) else: diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index b42925f89f..35f86809e3 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -442,7 +442,7 @@ class ProductionList(SphinxDirective): name, tokens = rule.split(':', 1) except ValueError: break - subnode = addnodes.production() + subnode = addnodes.production(rule) subnode['tokenname'] = name.strip() if subnode['tokenname']: idname = nodes.make_id('grammar-token-%s' % subnode['tokenname']) diff --git a/sphinx/environment/collectors/asset.py b/sphinx/environment/collectors/asset.py index a0c0094633..572dea7a45 100644 --- a/sphinx/environment/collectors/asset.py +++ b/sphinx/environment/collectors/asset.py @@ -100,6 +100,9 @@ class ImageCollector(EnvironmentCollector): filename) try: mimetype = guess_mimetype(filename) + if mimetype is None: + basename, suffix = path.splitext(filename) + mimetype = 'image/x-' + suffix[1:] if mimetype not in candidates: globbed.setdefault(mimetype, []).append(new_imgpath) except OSError as err: diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py index 2243e0644f..d38b749f04 100644 --- a/sphinx/ext/apidoc.py +++ b/sphinx/ext/apidoc.py @@ -56,6 +56,8 @@ template_dir = path.join(package_dir, 'templates', 'apidoc') def makename(package, module): # type: (str, str) -> str """Join package and module with a dot.""" + warnings.warn('makename() is deprecated.', + RemovedInSphinx40Warning) # Both package and module can be None/empty. if package: name = package @@ -66,6 +68,12 @@ def makename(package, module): return name +def module_join(*modnames): + # type: (*str) -> str + """Join module names with dots.""" + return '.'.join(filter(None, modnames)) + + def write_file(name, text, opts): # type: (str, str, Any) -> None """Write the output file for module/package .""" @@ -97,7 +105,7 @@ def format_directive(module, package=None): """Create the automodule directive and add the options.""" warnings.warn('format_directive() is deprecated.', RemovedInSphinx40Warning) - directive = '.. automodule:: %s\n' % makename(package, module) + directive = '.. automodule:: %s\n' % module_join(package, module) for option in OPTIONS: directive += ' :%s:\n' % option return directive @@ -106,7 +114,7 @@ def format_directive(module, package=None): def create_module_file(package, basename, opts): # type: (str, str, Any) -> None """Build the text of the file and write the file.""" - qualname = makename(package, basename) + qualname = module_join(package, basename) context = { 'show_headings': not opts.noheadings, 'basename': basename, @@ -123,17 +131,18 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs, is_ # build a list of sub packages (directories containing an INITPY file) subpackages = [sub for sub in subs if not shall_skip(path.join(root, sub, INITPY), opts, excludes)] - subpackages = [makename(makename(master_package, subroot), pkgname) + subpackages = [module_join(master_package, subroot, pkgname) for pkgname in subpackages] # build a list of sub modules submodules = [path.splitext(sub)[0] for sub in py_files - if not shall_skip(path.join(root, sub), opts, excludes) and + if not is_skipped_module(path.join(root, sub), opts, excludes) and sub != INITPY] - submodules = [makename(master_package, makename(subroot, modname)) + submodules = [module_join(master_package, subroot, modname) for modname in submodules] + pkgname = module_join(master_package, subroot) context = { - 'pkgname': makename(master_package, subroot), + 'pkgname': pkgname, 'subpackages': subpackages, 'submodules': submodules, 'is_namespace': is_namespace, @@ -143,7 +152,7 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs, is_ 'show_headings': not opts.noheadings, } text = ReSTRenderer(template_dir).render('package.rst', context) - write_file(makename(master_package, subroot), text, opts) + write_file(pkgname, text, opts) if submodules and opts.separatemodules: for submodule in submodules: @@ -198,6 +207,19 @@ def shall_skip(module, opts, excludes=[]): return False +def is_skipped_module(filename, opts, excludes): + # type: (str, Any, List[str]) -> bool + """Check if we want to skip this module.""" + if not path.exists(filename): + # skip if the file doesn't exist + return True + elif path.basename(filename).startswith('_') and not opts.includeprivate: + # skip if the module has a "private" name + return True + else: + return False + + def recurse_tree(rootpath, excludes, opts): # type: (str, List[str], Any) -> List[str] """ @@ -250,12 +272,12 @@ def recurse_tree(rootpath, excludes, opts): if not is_namespace or len(py_files) > 0: create_package_file(root, root_package, subpackage, py_files, opts, subs, is_namespace, excludes) - toplevels.append(makename(root_package, subpackage)) + toplevels.append(module_join(root_package, subpackage)) else: # if we are at the root level, we don't require it to be a package assert root == rootpath and root_package is None for py_file in py_files: - if not shall_skip(path.join(rootpath, py_file), opts): + if not is_skipped_module(path.join(rootpath, py_file), opts, excludes): module = path.splitext(py_file)[0] create_module_file(root_package, module, opts) toplevels.append(module) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index b3c04e464a..07bf54e10c 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -17,6 +17,7 @@ from typing import Any from docutils.statemachine import StringList import sphinx +from sphinx.config import ENUM from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.ext.autodoc.importer import import_object, get_object_members from sphinx.ext.autodoc.mock import mock @@ -65,6 +66,7 @@ def identity(x): ALL = object() INSTANCEATTR = object() +SLOTSATTR = object() def members_option(arg): @@ -363,8 +365,8 @@ class Documenter: return False return True - def format_args(self): - # type: () -> str + def format_args(self, **kwargs): + # type: (Any) -> str """Format the argument signature of *self.object*. Should return None if the object does not have a signature. @@ -383,8 +385,8 @@ class Documenter: # directives of course) return '.'.join(self.objpath) or self.modname - def format_signature(self): - # type: () -> str + def format_signature(self, **kwargs): + # type: (Any) -> str """Format the signature (arguments and return annotation) of the object. Let the user process it via the ``autodoc-process-signature`` event. @@ -395,7 +397,11 @@ class Documenter: else: # try to introspect the signature try: - args = self.format_args() + try: + args = self.format_args(**kwargs) + except TypeError: + # retry without arguments for old documenters + args = self.format_args() except Exception as err: logger.warning(__('error while formatting arguments for %s: %s') % (self.fullname, err), type='autodoc') @@ -954,15 +960,15 @@ class DocstringSignatureMixin: return lines return super().get_doc(None, ignore) # type: ignore - def format_signature(self): - # type: () -> str + def format_signature(self, **kwargs): + # type: (Any) -> str if self.args is None and self.env.config.autodoc_docstring_signature: # type: ignore # only act if a signature is not explicitly given already, and if # the feature is enabled result = self._find_signature() if result is not None: self.args, self.retann = result - return super().format_signature() # type: ignore + return super().format_signature(**kwargs) # type: ignore class DocstringStripSignatureMixin(DocstringSignatureMixin): @@ -970,8 +976,8 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin): Mixin for AttributeDocumenter to provide the feature of stripping any function signature from the docstring. """ - def format_signature(self): - # type: () -> str + def format_signature(self, **kwargs): + # type: (Any) -> str if self.args is None and self.env.config.autodoc_docstring_signature: # type: ignore # only act if a signature is not explicitly given already, and if # the feature is enabled @@ -981,7 +987,7 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin): # DocstringSignatureMixin.format_signature. # Documenter.format_signature use self.args value to format. _args, self.retann = result - return super().format_signature() + return super().format_signature(**kwargs) class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: ignore @@ -998,8 +1004,11 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ return (inspect.isfunction(member) or inspect.isbuiltin(member) or (inspect.isroutine(member) and isinstance(parent, ModuleDocumenter))) - def format_args(self): - # type: () -> str + def format_args(self, **kwargs): + # type: (Any) -> str + if self.env.config.autodoc_typehints == 'none': + kwargs.setdefault('show_annotation', False) + if inspect.isbuiltin(self.object) or inspect.ismethoddescriptor(self.object): # cannot introspect arguments of a C function or method return None @@ -1009,9 +1018,9 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ not inspect.isbuiltin(self.object) and not inspect.isclass(self.object) and hasattr(self.object, '__call__')): - args = Signature(self.object.__call__).format_args() + args = Signature(self.object.__call__).format_args(**kwargs) else: - args = Signature(self.object).format_args() + args = Signature(self.object).format_args(**kwargs) except TypeError: if (inspect.is_builtin_class_method(self.object, '__new__') and inspect.is_builtin_class_method(self.object, '__init__')): @@ -1022,10 +1031,10 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ # signature without the first argument. try: sig = Signature(self.object.__new__, bound_method=True, has_retval=False) - args = sig.format_args() + args = sig.format_args(**kwargs) except TypeError: sig = Signature(self.object.__init__, bound_method=True, has_retval=False) - args = sig.format_args() + args = sig.format_args(**kwargs) # escape backslashes for reST args = args.replace('\\', '\\\\') @@ -1053,8 +1062,8 @@ class DecoratorDocumenter(FunctionDocumenter): # must be lower than FunctionDocumenter priority = -1 - def format_args(self): - args = super().format_args() + def format_args(self, **kwargs): + args = super().format_args(**kwargs) if ',' in args: return args else: @@ -1097,8 +1106,11 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: self.doc_as_attr = True return ret - def format_args(self): - # type: () -> str + def format_args(self, **kwargs): + # type: (Any) -> str + if self.env.config.autodoc_typehints == 'none': + kwargs.setdefault('show_annotation', False) + # for classes, the relevant signature is the __init__ method's initmeth = self.get_attr(self.object, '__init__', None) # classes without __init__ method, default __init__ or @@ -1108,18 +1120,19 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)): return None try: - return Signature(initmeth, bound_method=True, has_retval=False).format_args() + sig = Signature(initmeth, bound_method=True, has_retval=False) + return sig.format_args(**kwargs) except TypeError: # still not possible: happens e.g. for old-style classes # with __init__ in C return None - def format_signature(self): - # type: () -> str + def format_signature(self, **kwargs): + # type: (Any) -> str if self.doc_as_attr: return '' - return super().format_signature() + return super().format_signature(**kwargs) def add_directive_header(self, sig): # type: (str) -> None @@ -1310,15 +1323,18 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: return ret - def format_args(self): - # type: () -> str + def format_args(self, **kwargs): + # type: (Any) -> str + if self.env.config.autodoc_typehints == 'none': + kwargs.setdefault('show_annotation', False) + if inspect.isbuiltin(self.object) or inspect.ismethoddescriptor(self.object): # can never get arguments of a C function or method return None if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name): - args = Signature(self.object, bound_method=False).format_args() + args = Signature(self.object, bound_method=False).format_args(**kwargs) else: - args = Signature(self.object, bound_method=True).format_args() + args = Signature(self.object, bound_method=True).format_args(**kwargs) # escape backslashes for reST args = args.replace('\\', '\\\\') return args @@ -1329,6 +1345,8 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: sourcename = self.get_sourcename() obj = self.parent.__dict__.get(self.object_name, self.object) + if inspect.isabstractmethod(obj): + self.add_line(' :abstractmethod:', sourcename) if inspect.iscoroutinefunction(obj): self.add_line(' :async:', sourcename) if inspect.isclassmethod(obj): @@ -1446,7 +1464,10 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): # def add_directive_header(self, sig): # type: (str) -> None super().add_directive_header(sig) - self.add_line(' :property:', self.get_sourcename()) + sourcename = self.get_sourcename() + if inspect.isabstractmethod(self.object): + self.add_line(' :abstractmethod:', sourcename) + self.add_line(' :property:', sourcename) class InstanceAttributeDocumenter(AttributeDocumenter): @@ -1481,6 +1502,55 @@ class InstanceAttributeDocumenter(AttributeDocumenter): super().add_content(more_content, no_docstring=True) +class SlotsAttributeDocumenter(AttributeDocumenter): + """ + Specialized Documenter subclass for attributes that cannot be imported + because they are attributes in __slots__. + """ + objtype = 'slotsattribute' + directivetype = 'attribute' + member_order = 60 + + # must be higher than AttributeDocumenter + priority = 11 + + @classmethod + def can_document_member(cls, member, membername, isattr, parent): + # type: (Any, str, bool, Any) -> bool + """This documents only SLOTSATTR members.""" + return member is SLOTSATTR + + def import_object(self): + # type: () -> bool + """Never import anything.""" + # disguise as an attribute + self.objtype = 'attribute' + self._datadescriptor = True + + with mock(self.env.config.autodoc_mock_imports): + try: + ret = import_object(self.modname, self.objpath[:-1], 'class', + attrgetter=self.get_attr, + warningiserror=self.env.config.autodoc_warningiserror) + self.module, _, _, self.parent = ret + return True + except ImportError as exc: + logger.warning(exc.args[0], type='autodoc', subtype='import_object') + self.env.note_reread() + return False + + def get_doc(self, encoding=None, ignore=1): + # type: (str, int) -> List[List[str]] + """Decode and return lines of the docstring(s) for the object.""" + name = self.objpath[-1] + __slots__ = safe_getattr(self.parent, '__slots__', []) + if isinstance(__slots__, dict) and isinstance(__slots__.get(name), str): + docstring = prepare_docstring(__slots__[name]) + return [docstring] + else: + return [] + + def get_documenters(app): # type: (Sphinx) -> Dict[str, Type[Documenter]] """Returns registered Documenter classes""" @@ -1509,6 +1579,7 @@ def setup(app): app.add_autodocumenter(AttributeDocumenter) app.add_autodocumenter(PropertyDocumenter) app.add_autodocumenter(InstanceAttributeDocumenter) + app.add_autodocumenter(SlotsAttributeDocumenter) app.add_config_value('autoclass_content', 'class', True) app.add_config_value('autodoc_member_order', 'alphabetic', True) @@ -1516,6 +1587,7 @@ def setup(app): app.add_config_value('autodoc_default_options', {}, True) app.add_config_value('autodoc_docstring_signature', True, True) app.add_config_value('autodoc_mock_imports', [], True) + app.add_config_value('autodoc_typehints', "signature", True, ENUM("signature", "none")) app.add_config_value('autodoc_warningiserror', True, True) app.add_config_value('autodoc_inherit_docstrings', True, True) app.add_event('autodoc-process-docstring') diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index 557461fd4e..18c6fc8f16 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -15,7 +15,7 @@ from collections import namedtuple from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.util import logging -from sphinx.util.inspect import isenumclass, safe_getattr +from sphinx.util.inspect import isclass, isenumclass, safe_getattr if False: # For type annotation @@ -127,6 +127,13 @@ def get_object_members(subject, objpath, attrgetter, analyzer=None): if name not in superclass.__dict__: members[name] = Attribute(name, True, value) + # members in __slots__ + if isclass(subject) and hasattr(subject, '__slots__'): + from sphinx.ext.autodoc import SLOTSATTR + + for name in subject.__slots__: + members[name] = Attribute(name, True, SLOTSATTR) + # other members for name in dir(subject): try: diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py index de46cec520..3d55ad7491 100644 --- a/sphinx/ext/autosectionlabel.py +++ b/sphinx/ext/autosectionlabel.py @@ -55,7 +55,7 @@ def register_sections_as_label(app, document): if name in labels: logger.warning(__('duplicate label %s, other instance in %s'), name, app.env.doc2path(labels[name][0]), - location=node) + location=node, type='autosectionlabel', subtype=docname) anonlabels[name] = docname, labelid labels[name] = docname, labelid, sectname diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 825fa197c9..cf768dc4f8 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -63,7 +63,7 @@ from typing import List, cast from docutils import nodes from docutils.parsers.rst import directives -from docutils.parsers.rst.states import RSTStateMachine, state_classes +from docutils.parsers.rst.states import RSTStateMachine, Struct, state_classes from docutils.statemachine import StringList import sphinx @@ -175,7 +175,10 @@ _app = None # type: Sphinx class FakeDirective(DocumenterBridge): def __init__(self): # type: () -> None - super().__init__({}, None, Options(), 0, None) # type: ignore + settings = Struct(tab_width=8) + document = Struct(settings=settings) + state = Struct(document=document) + super().__init__({}, None, Options(), 0, state) # type: ignore def get_documenter(app, obj, parent): @@ -329,7 +332,12 @@ class Autosummary(SphinxDirective): # -- Grab the signature - sig = documenter.format_signature() + try: + sig = documenter.format_signature(show_annotation=False) + except TypeError: + # the documenter does not support ``show_annotation`` option + sig = documenter.format_signature() + if not sig: sig = '' else: @@ -436,16 +444,26 @@ def mangle_signature(sig, max_chars=30): # Remove parenthesis s = re.sub(r"^\((.*)\)$", r"\1", s).strip() - # Strip strings (which can contain things that confuse the code below) - s = re.sub(r"\\\\", "", s) - s = re.sub(r"\\'", "", s) - s = re.sub(r"'[^']*'", "", s) + # Strip literals (which can contain things that confuse the code below) + s = re.sub(r"\\\\", "", s) # escaped backslash (maybe inside string) + s = re.sub(r"\\'", "", s) # escaped single quote + s = re.sub(r'\\"', "", s) # escaped double quote + s = re.sub(r"'[^']*'", "", s) # string literal (w/ single quote) + s = re.sub(r'"[^"]*"', "", s) # string literal (w/ double quote) + + # Strip complex objects (maybe default value of arguments) + while re.search(r'\([^)]*\)', s): # contents of parenthesis (ex. NamedTuple(attr=...)) + s = re.sub(r'\([^)]*\)', '', s) + while re.search(r'<[^>]*>', s): # contents of angle brackets (ex. ) + s = re.sub(r'<[^>]*>', '', s) + while re.search(r'{[^}]*}', s): # contents of curly brackets (ex. dict) + s = re.sub(r'{[^}]*}', '', s) # Parse the signature to arguments + options args = [] # type: List[str] opts = [] # type: List[str] - opt_re = re.compile(r"^(.*, |)([a-zA-Z0-9_*]+)=") + opt_re = re.compile(r"^(.*, |)([a-zA-Z0-9_*]+)\s*=\s*") while s: m = opt_re.search(s) if not m: diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index c894579204..129c43f650 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -25,7 +25,7 @@ import pydoc import re import sys -from jinja2 import FileSystemLoader, TemplateNotFound +from jinja2 import BaseLoader, FileSystemLoader, TemplateNotFound from jinja2.sandbox import SandboxedEnvironment import sphinx.locale @@ -35,9 +35,9 @@ from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.jinja2glue import BuiltinTemplateLoader from sphinx.locale import __ from sphinx.registry import SphinxComponentRegistry +from sphinx.util import rst from sphinx.util.inspect import safe_getattr from sphinx.util.osutil import ensuredir -from sphinx.util.rst import escape as rst_escape if False: # For type annotation @@ -59,12 +59,14 @@ def setup_documenters(app): from sphinx.ext.autodoc import ( ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, FunctionDocumenter, MethodDocumenter, AttributeDocumenter, - InstanceAttributeDocumenter + InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, + SlotsAttributeDocumenter, ) documenters = [ ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, FunctionDocumenter, MethodDocumenter, AttributeDocumenter, - InstanceAttributeDocumenter + InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, + SlotsAttributeDocumenter, ] # type: List[Type[Documenter]] for documenter in documenters: app.registry.add_documenter(documenter.objtype, documenter) @@ -87,6 +89,42 @@ def _underline(title, line='='): return title + '\n' + line * len(title) +class AutosummaryRenderer: + """A helper class for rendering.""" + + def __init__(self, builder, template_dir): + # type: (Builder, str) -> None + loader = None # type: BaseLoader + template_dirs = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')] + if builder is None: + if template_dir: + template_dirs.insert(0, template_dir) + loader = FileSystemLoader(template_dirs) + else: + # allow the user to override the templates + loader = BuiltinTemplateLoader() + loader.init(builder, dirs=template_dirs) + + self.env = SandboxedEnvironment(loader=loader) + self.env.filters['escape'] = rst.escape + self.env.filters['e'] = rst.escape + self.env.filters['underline'] = _underline + + def exists(self, template_name): + # type: (str) -> bool + """Check if template file exists.""" + try: + self.env.get_template(template_name) + return True + except TemplateNotFound: + return False + + def render(self, template_name, context): + # type: (str, Dict) -> str + """Render a template file.""" + return self.env.get_template(template_name).render(context) + + # -- Generating output --------------------------------------------------------- def generate_autosummary_docs(sources, # type: List[str] @@ -114,26 +152,7 @@ def generate_autosummary_docs(sources, # type: List[str] if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] - # create our own templating environment - template_dirs = None # type: List[str] - template_dirs = [os.path.join(package_dir, 'ext', - 'autosummary', 'templates')] - - template_loader = None # type: Union[BuiltinTemplateLoader, FileSystemLoader] - if builder is not None: - # allow the user to override the templates - template_loader = BuiltinTemplateLoader() - template_loader.init(builder, dirs=template_dirs) - else: - if template_dir: - template_dirs.insert(0, template_dir) - template_loader = FileSystemLoader(template_dirs) - template_env = SandboxedEnvironment(loader=template_loader) - template_env.filters['underline'] = _underline - - # replace the builtin html filters - template_env.filters['escape'] = rst_escape - template_env.filters['e'] = rst_escape + template = AutosummaryRenderer(builder, template_dir) # read items = find_autosummary_in_files(sources) @@ -189,14 +208,10 @@ def generate_autosummary_docs(sources, # type: List[str] with open(fn, 'w') as f: doc = get_documenter(app, obj, parent) - if template_name is not None: - template = template_env.get_template(template_name) - else: - try: - template = template_env.get_template('autosummary/%s.rst' - % doc.objtype) - except TemplateNotFound: - template = template_env.get_template('autosummary/base.rst') + if template_name is None: + template_name = 'autosummary/%s.rst' % doc.objtype + if not template.exists(template_name): + template_name = 'autosummary/base.rst' def get_members(obj, types, include_public=[], imported=True): # type: (Any, Set[str], List[str], bool) -> Tuple[List[str], List[str]] # NOQA @@ -273,7 +288,7 @@ def generate_autosummary_docs(sources, # type: List[str] ns['objtype'] = doc.objtype ns['underline'] = len(name) * '=' - rendered = template.render(**ns) + rendered = template.render(template_name, ns) f.write(rendered) # descend recursively to new files diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 63beecd616..6c9489046b 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -79,6 +79,8 @@ class CoverageBuilder(Builder): self.config.coverage_ignore_classes) self.fun_ignorexps = compile_regex_list('coverage_ignore_functions', self.config.coverage_ignore_functions) + self.py_ignorexps = compile_regex_list('coverage_ignore_pyobjects', + self.config.coverage_ignore_pyobjects) def get_outdated_docs(self): # type: () -> str @@ -130,6 +132,12 @@ class CoverageBuilder(Builder): op.write(' * %-50s [%9s]\n' % (name, typ)) op.write('\n') + def ignore_pyobj(self, full_name): + for exp in self.py_ignorexps: + if exp.search(full_name): + return True + return False + def build_py_coverage(self): # type: () -> None objects = self.env.domaindata['py']['objects'] @@ -143,7 +151,7 @@ class CoverageBuilder(Builder): if exp.match(mod_name): ignore = True break - if ignore: + if ignore or self.ignore_pyobj(mod_name): continue try: @@ -169,6 +177,8 @@ class CoverageBuilder(Builder): continue full_name = '%s.%s' % (mod_name, name) + if self.ignore_pyobj(full_name): + continue if inspect.isfunction(obj): if full_name not in objects: @@ -209,11 +219,11 @@ class CoverageBuilder(Builder): if skip_undoc and not attr.__doc__: # skip methods without docstring if wished continue - full_attr_name = '%s.%s' % (full_name, attr_name) + if self.ignore_pyobj(full_attr_name): + continue if full_attr_name not in objects: attrs.append(attr_name) - if attrs: # some attributes are undocumented classes[name] = attrs @@ -270,6 +280,7 @@ def setup(app): app.add_config_value('coverage_ignore_modules', [], False) app.add_config_value('coverage_ignore_functions', [], False) app.add_config_value('coverage_ignore_classes', [], False) + app.add_config_value('coverage_ignore_pyobjects', [], False) app.add_config_value('coverage_c_path', [], False) app.add_config_value('coverage_c_regexes', {}, False) app.add_config_value('coverage_ignore_c_items', {}, False) diff --git a/sphinx/templates/quickstart/make.bat.new_t b/sphinx/templates/quickstart/make.bat.new_t index 50a12e7af6..1bb2f34896 100644 --- a/sphinx/templates/quickstart/make.bat.new_t +++ b/sphinx/templates/quickstart/make.bat.new_t @@ -25,11 +25,11 @@ if errorlevel 9009 ( exit /b 1 ) -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% goto end :help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end popd diff --git a/sphinx/templates/quickstart/make.bat_t b/sphinx/templates/quickstart/make.bat_t index 004f1f9122..7745855668 100644 --- a/sphinx/templates/quickstart/make.bat_t +++ b/sphinx/templates/quickstart/make.bat_t @@ -9,7 +9,7 @@ if "%SPHINXBUILD%" == "" ( ) set BUILDDIR={{ rbuilddir }} set SOURCEDIR={{ rsrcdir }} -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SOURCEDIR% +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %O% %SOURCEDIR% set I18NSPHINXOPTS=%SPHINXOPTS% %SOURCEDIR% if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_elements.papersize=%PAPER%paper %ALLSPHINXOPTS% diff --git a/sphinx/themes/basic/static/searchtools.js b/sphinx/themes/basic/static/searchtools.js index bdc270655b..6031f99131 100644 --- a/sphinx/themes/basic/static/searchtools.js +++ b/sphinx/themes/basic/static/searchtools.js @@ -319,12 +319,13 @@ var Search = { for (var prefix in objects) { for (var name in objects[prefix]) { var fullname = (prefix ? prefix + '.' : '') + name; - if (fullname.toLowerCase().indexOf(object) > -1) { + var fullnameLower = fullname.toLowerCase() + if (fullnameLower.indexOf(object) > -1) { var score = 0; - var parts = fullname.split('.'); + var parts = fullnameLower.split('.'); // check for different match types: exact matches of full name or // "last name" (i.e. last dotted part) - if (fullname == object || parts[parts.length - 1] == object) { + if (fullnameLower == object || parts[parts.length - 1] == object) { score += Scorer.objNameMatch; // matches in last name } else if (parts[parts.length - 1].indexOf(object) > -1) { diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html index 9dbae6d0a5..2f1a0b4a0f 100644 --- a/sphinx/themes/haiku/layout.html +++ b/sphinx/themes/haiku/layout.html @@ -51,7 +51,7 @@ -
+
{#{%- if display_toc %}

{{ _('Table of Contents') }}

diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html index 852ac967f7..08f8970fcb 100644 --- a/sphinx/themes/scrolls/layout.html +++ b/sphinx/themes/scrolls/layout.html @@ -42,7 +42,9 @@ {{ toc }}
{%- endif %} +
{% block body %}{% endblock %} +
{% endblock %} diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py index 89534f5aee..0caee3af66 100644 --- a/sphinx/util/i18n.py +++ b/sphinx/util/i18n.py @@ -244,7 +244,7 @@ date_format_mappings = { '%x': 'medium', # Locale’s appropriate date representation. '%X': 'medium', # Locale’s appropriate time representation. '%y': 'YY', # Year without century as a zero-padded decimal number. - '%Y': 'YYYY', # Year with century as a decimal number. + '%Y': 'yyyy', # Year with century as a decimal number. '%Z': 'zzzz', # Time zone name (no characters if no time zone exists). '%%': '%', } diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index caf333493f..9dc422778a 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -170,6 +170,12 @@ def isdescriptor(x): return False +def isabstractmethod(obj): + # type: (Any) -> bool + """Check if the object is an abstractmethod.""" + return safe_getattr(obj, '__isabstractmethod__', False) is True + + def isattributedescriptor(obj): # type: (Any) -> bool """Check if the object is an attribute like descriptor.""" @@ -229,7 +235,7 @@ def isproperty(obj): def safe_getattr(obj, name, *defargs): - # type: (Any, str, str) -> object + # type: (Any, str, Any) -> Any """A getattr() that turns all exceptions into AttributeErrors.""" try: return getattr(obj, name, *defargs) @@ -317,9 +323,9 @@ def is_builtin_class_method(obj, attr_name): classes = [c for c in inspect.getmro(obj) if attr_name in c.__dict__] cls = classes[0] if classes else object - if not hasattr(builtins, safe_getattr(cls, '__name__', '')): # type: ignore + if not hasattr(builtins, safe_getattr(cls, '__name__', '')): return False - return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls # type: ignore + return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls class Signature: @@ -391,8 +397,8 @@ class Signature: else: return None - def format_args(self): - # type: () -> str + def format_args(self, show_annotation=True): + # type: (bool) -> str args = [] last_kind = None for i, param in enumerate(self.parameters.values()): @@ -413,7 +419,7 @@ class Signature: param.POSITIONAL_OR_KEYWORD, param.KEYWORD_ONLY): arg.write(param.name) - if param.annotation is not param.empty: + if show_annotation and param.annotation is not param.empty: if isinstance(param.annotation, str) and param.name in self.annotations: arg.write(': ') arg.write(self.format_annotation(self.annotations[param.name])) @@ -503,6 +509,8 @@ class Signature: args = ', '.join(self.format_annotation(a) for a in annotation.__args__[:-1]) returns = self.format_annotation(annotation.__args__[-1]) return '%s[[%s], %s]' % (qualname, args, returns) + elif annotation._special: + return qualname else: args = ', '.join(self.format_annotation(a) for a in annotation.__args__) return '%s[%s]' % (qualname, args) @@ -534,8 +542,11 @@ class Signature: not hasattr(annotation, '__tuple_params__')): # This is for Python 3.6+, 3.5 case is handled below params = annotation.__args__ - param_str = ', '.join(self.format_annotation(p) for p in params) - return '%s[%s]' % (qualname, param_str) + if params: + param_str = ', '.join(self.format_annotation(p) for p in params) + return '%s[%s]' % (qualname, param_str) + else: + return qualname elif (hasattr(typing, 'GenericMeta') and # for py36 or below isinstance(annotation, typing.GenericMeta)): # In Python 3.5.2+, all arguments are stored in __args__, diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 60e0144b07..58c6a66981 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -31,7 +31,7 @@ logger = logging.getLogger(__name__) # \x00 means the "<" was backslash-escaped -explicit_title_re = re.compile(r'^(.+?)\s*(?$', re.DOTALL) +explicit_title_re = re.compile(r'^(.+?)\s*(?$', re.DOTALL) caption_ref_re = explicit_title_re # b/w compat alias diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index b78dd1fcf9..38e2f35515 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -116,7 +116,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): def visit_desc_addname(self, node): # type: (nodes.Element) -> None - self.body.append(self.starttag(node, 'code', '', CLASS='descclassname')) + self.body.append(self.starttag(node, 'code', '', CLASS='sig-prename descclassname')) def depart_desc_addname(self, node): # type: (nodes.Element) -> None @@ -140,7 +140,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): def visit_desc_name(self, node): # type: (nodes.Element) -> None - self.body.append(self.starttag(node, 'code', '', CLASS='descname')) + self.body.append(self.starttag(node, 'code', '', CLASS='sig-name descname')) def depart_desc_name(self, node): # type: (nodes.Element) -> None @@ -175,7 +175,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): if self.optional_param_level == 0: self.required_params_left -= 1 if not node.hasattr('noemph'): - self.body.append('') + self.body.append('') def depart_desc_parameter(self, node): # type: (nodes.Element) -> None diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 803dd1dbcd..ceaf484582 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -213,7 +213,17 @@ ADDITIONAL_SETTINGS = { 'fncychap': '', 'geometry': '\\usepackage[dvipdfm]{geometry}', }, -} # type: Dict[str, Dict[str, Any]] + + # special settings for latex_engine + language_code + ('xelatex', 'fr'): { + # use babel instead of polyglossia by default + 'polyglossia': '', + 'babel': '\\usepackage{babel}', + }, + ('xelatex', 'zh'): { + 'fontenc': '\\usepackage{xeCJK}', + }, +} # type: Dict[Any, Dict[str, Any]] EXTRA_RE = re.compile(r'^(.*\S)\s+\(([^()]*)\)\s*$') diff --git a/tests/roots/test-ext-autodoc/target/abstractmethods.py b/tests/roots/test-ext-autodoc/target/abstractmethods.py new file mode 100644 index 0000000000..a4396d5c93 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/abstractmethods.py @@ -0,0 +1,29 @@ +from abc import abstractmethod + + +class Base(): + def meth(self): + pass + + @abstractmethod + def abstractmeth(self): + pass + + @staticmethod + @abstractmethod + def staticmeth(): + pass + + @classmethod + @abstractmethod + def classmeth(cls): + pass + + @property + @abstractmethod + def prop(self): + pass + + @abstractmethod + async def coroutinemeth(self): + pass diff --git a/tests/roots/test-ext-autodoc/target/slots.py b/tests/roots/test-ext-autodoc/target/slots.py new file mode 100644 index 0000000000..44e7503205 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/slots.py @@ -0,0 +1,11 @@ +class Foo: + __slots__ = ['attr'] + + +class Bar: + __slots__ = {'attr1': 'docstring of attr1', + 'attr2': 'docstring of attr2', + 'attr3': None} + + def __init__(self): + self.attr2 = None #: docstring of instance attr2 diff --git a/tests/roots/test-ext-autodoc/target/typehints.py b/tests/roots/test-ext-autodoc/target/typehints.py new file mode 100644 index 0000000000..eedaab3b99 --- /dev/null +++ b/tests/roots/test-ext-autodoc/target/typehints.py @@ -0,0 +1,10 @@ +def incr(a: int, b: int = 1) -> int: + return a + b + + +class Math: + def __init__(self, s: str, o: object = None) -> None: + pass + + def incr(self, a: int, b: int = 1) -> int: + return a + b diff --git a/tests/roots/test-ext-autosummary/autosummary_dummy_module.py b/tests/roots/test-ext-autosummary/autosummary_dummy_module.py index 5506d0bc9f..02e6c0e7df 100644 --- a/tests/roots/test-ext-autosummary/autosummary_dummy_module.py +++ b/tests/roots/test-ext-autosummary/autosummary_dummy_module.py @@ -1,4 +1,5 @@ from os import * # NOQA +from typing import Union class Foo: @@ -11,3 +12,7 @@ class Foo: @property def baz(self): pass + + +def bar(x: Union[int, str], y: int = 1): + pass diff --git a/tests/roots/test-ext-autosummary/index.rst b/tests/roots/test-ext-autosummary/index.rst index fc84927bb5..c52e96ed9b 100644 --- a/tests/roots/test-ext-autosummary/index.rst +++ b/tests/roots/test-ext-autosummary/index.rst @@ -8,4 +8,5 @@ autosummary_dummy_module autosummary_dummy_module.Foo + autosummary_dummy_module.bar autosummary_importfail diff --git a/tests/roots/test-ext-coverage/conf.py b/tests/roots/test-ext-coverage/conf.py new file mode 100644 index 0000000000..d3ec6e87f3 --- /dev/null +++ b/tests/roots/test-ext-coverage/conf.py @@ -0,0 +1,12 @@ +import os +import sys + +sys.path.insert(0, os.path.abspath('.')) + +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.coverage'] + +coverage_ignore_pyobjects = [ + r'^coverage_ignored(\..*)?$', + r'\.Ignored$', + r'\.Documented\.ignored\d$', +] diff --git a/tests/roots/test-ext-coverage/coverage_ignored.py b/tests/roots/test-ext-coverage/coverage_ignored.py new file mode 100644 index 0000000000..b762955010 --- /dev/null +++ b/tests/roots/test-ext-coverage/coverage_ignored.py @@ -0,0 +1,22 @@ +class Documented: + """Documented""" + + def ignored1(self): + pass + + def ignored2(self): + pass + + def not_ignored1(self): + pass + + def not_ignored2(self): + pass + + +class Ignored: + pass + + +class NotIgnored: + pass diff --git a/tests/roots/test-ext-coverage/coverage_not_ignored.py b/tests/roots/test-ext-coverage/coverage_not_ignored.py new file mode 100644 index 0000000000..b762955010 --- /dev/null +++ b/tests/roots/test-ext-coverage/coverage_not_ignored.py @@ -0,0 +1,22 @@ +class Documented: + """Documented""" + + def ignored1(self): + pass + + def ignored2(self): + pass + + def not_ignored1(self): + pass + + def not_ignored2(self): + pass + + +class Ignored: + pass + + +class NotIgnored: + pass diff --git a/tests/roots/test-ext-coverage/index.rst b/tests/roots/test-ext-coverage/index.rst new file mode 100644 index 0000000000..b8468987ee --- /dev/null +++ b/tests/roots/test-ext-coverage/index.rst @@ -0,0 +1,6 @@ +.. automodule:: coverage_ignored + :members: + + +.. automodule:: coverage_not_ignored + :members: diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 0c3de1fae8..f60b2bb0bc 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -1317,6 +1317,46 @@ def test_instance_attributes(app): ] +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_slots(app): + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'module', 'target.slots', options) + assert list(actual) == [ + '', + '.. py:module:: target.slots', + '', + '', + '.. py:class:: Bar()', + ' :module: target.slots', + '', + ' ', + ' .. py:attribute:: Bar.attr1', + ' :module: target.slots', + ' ', + ' docstring of attr1', + ' ', + ' ', + ' .. py:attribute:: Bar.attr2', + ' :module: target.slots', + ' ', + ' docstring of instance attr2', + ' ', + ' ', + ' .. py:attribute:: Bar.attr3', + ' :module: target.slots', + ' ', + '', + '.. py:class:: Foo', + ' :module: target.slots', + '', + ' ', + ' .. py:attribute:: Foo.attr', + ' :module: target.slots', + ' ', + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_enum_class(app): options = {"members": None, @@ -1482,6 +1522,55 @@ def test_mocked_module_imports(app, warning): assert warning.getvalue() == '' +@pytest.mark.usefixtures('setup_test') +def test_abstractmethods(): + options = {"members": None, + "undoc-members": None} + actual = do_autodoc(app, 'module', 'target.abstractmethods', options) + assert list(actual) == [ + '', + '.. py:module:: target.abstractmethods', + '', + '', + '.. py:class:: Base', + ' :module: target.abstractmethods', + '', + ' ', + ' .. py:method:: Base.abstractmeth()', + ' :module: target.abstractmethods', + ' :abstractmethod:', + ' ', + ' ', + ' .. py:method:: Base.classmeth()', + ' :module: target.abstractmethods', + ' :abstractmethod:', + ' :classmethod:', + ' ', + ' ', + ' .. py:method:: Base.coroutinemeth()', + ' :module: target.abstractmethods', + ' :abstractmethod:', + ' :async:', + ' ', + ' ', + ' .. py:method:: Base.meth()', + ' :module: target.abstractmethods', + ' ', + ' ', + ' .. py:method:: Base.prop', + ' :module: target.abstractmethods', + ' :abstractmethod:', + ' :property:', + ' ', + ' ', + ' .. py:method:: Base.staticmeth()', + ' :module: target.abstractmethods', + ' :abstractmethod:', + ' :staticmethod:', + ' ' + ] + + @pytest.mark.usefixtures('setup_test') def test_partialfunction(): options = {"members": None} @@ -1597,6 +1686,58 @@ def test_partialmethod(app): assert list(actual) == expected +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_typehints_signature(app): + app.config.autodoc_typehints = "signature" + + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'module', 'target.typehints', options) + assert list(actual) == [ + '', + '.. py:module:: target.typehints', + '', + '', + '.. py:class:: Math(s: str, o: object = None)', + ' :module: target.typehints', + '', + ' ', + ' .. py:method:: Math.incr(a: int, b: int = 1) -> int', + ' :module: target.typehints', + ' ', + '', + '.. py:function:: incr(a: int, b: int = 1) -> int', + ' :module: target.typehints', + '' + ] + + +@pytest.mark.sphinx('html', testroot='ext-autodoc') +def test_autodoc_typehints_none(app): + app.config.autodoc_typehints = "none" + + options = {"members": None, + "undoc-members": True} + actual = do_autodoc(app, 'module', 'target.typehints', options) + assert list(actual) == [ + '', + '.. py:module:: target.typehints', + '', + '', + '.. py:class:: Math(s, o = None)', + ' :module: target.typehints', + '', + ' ', + ' .. py:method:: Math.incr(a, b = 1) -> int', + ' :module: target.typehints', + ' ', + '', + '.. py:function:: incr(a, b = 1) -> int', + ' :module: target.typehints', + '' + ] + + @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_default_options(app): # no settings diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index f02394cf17..45e9935010 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -165,6 +165,16 @@ def test_latex_basic(app, status, warning): assert r'\renewcommand{\releasename}{}' in result +@pytest.mark.sphinx('latex', testroot='basic', confoverrides={'language': 'zh'}) +def test_latex_additional_settings_for_language_code(app, status, warning): + app.builder.build_all() + result = (app.outdir / 'test.tex').text(encoding='utf8') + print(result) + print(status.getvalue()) + print(warning.getvalue()) + assert r'\usepackage{xeCJK}' in result + + @pytest.mark.sphinx('latex', testroot='latex-title') def test_latex_title_after_admonitions(app, status, warning): app.builder.build_all() diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py index fac8a838f1..d438543bde 100644 --- a/tests/test_domain_py.py +++ b/tests/test_domain_py.py @@ -18,7 +18,10 @@ from sphinx.addnodes import ( desc, desc_addname, desc_annotation, desc_content, desc_name, desc_optional, desc_parameter, desc_parameterlist, desc_returns, desc_signature ) -from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain +from sphinx.domains import IndexEntry +from sphinx.domains.python import ( + py_sig_re, _pseudo_parse_arglist, PythonDomain, PythonModuleIndex +) from sphinx.testing import restructuredtext from sphinx.testing.util import assert_node @@ -335,7 +338,9 @@ def test_pymethod_options(app): " .. py:method:: meth4\n" " :async:\n" " .. py:method:: meth5\n" - " :property:\n") + " :property:\n" + " .. py:method:: meth6\n" + " :abstractmethod:\n") domain = app.env.get_domain('py') doctree = restructuredtext.parse(app, text) assert_node(doctree, (addnodes.index, @@ -350,6 +355,8 @@ def test_pymethod_options(app): addnodes.index, desc, addnodes.index, + desc, + addnodes.index, desc)])])) # method @@ -400,6 +407,16 @@ def test_pymethod_options(app): assert 'Class.meth5' in domain.objects assert domain.objects['Class.meth5'] == ('index', 'method') + # :abstractmethod: + assert_node(doctree[1][1][10], addnodes.index, + entries=[('single', 'meth6() (Class method)', 'Class.meth6', '', None)]) + assert_node(doctree[1][1][11], ([desc_signature, ([desc_annotation, "abstract "], + [desc_name, "meth6"], + [desc_parameterlist, ()])], + [desc_content, ()])) + assert 'Class.meth6' in domain.objects + assert domain.objects['Class.meth6'] == ('index', 'method') + def test_pyclassmethod(app): text = (".. py:class:: Class\n" @@ -460,3 +477,49 @@ def test_pyattribute(app): [desc_content, ()])) assert 'Class.attr' in domain.objects assert domain.objects['Class.attr'] == ('index', 'attribute') + + +@pytest.mark.sphinx(freshenv=True) +def test_module_index(app): + text = (".. py:module:: docutils\n" + ".. py:module:: sphinx\n" + ".. py:module:: sphinx.config\n" + ".. py:module:: sphinx.builders\n" + ".. py:module:: sphinx.builders.html\n" + ".. py:module:: sphinx_intl\n") + restructuredtext.parse(app, text) + index = PythonModuleIndex(app.env.get_domain('py')) + assert index.generate() == ( + [('d', [IndexEntry('docutils', 0, 'index', 'module-docutils', '', '', '')]), + ('s', [IndexEntry('sphinx', 1, 'index', 'module-sphinx', '', '', ''), + IndexEntry('sphinx.builders', 2, 'index', 'module-sphinx.builders', '', '', ''), # NOQA + IndexEntry('sphinx.builders.html', 2, 'index', 'module-sphinx.builders.html', '', '', ''), # NOQA + IndexEntry('sphinx.config', 2, 'index', 'module-sphinx.config', '', '', ''), + IndexEntry('sphinx_intl', 0, 'index', 'module-sphinx_intl', '', '', '')])], + False + ) + + +@pytest.mark.sphinx(freshenv=True) +def test_module_index_submodule(app): + text = ".. py:module:: sphinx.config\n" + restructuredtext.parse(app, text) + index = PythonModuleIndex(app.env.get_domain('py')) + assert index.generate() == ( + [('s', [IndexEntry('sphinx', 1, '', '', '', '', ''), + IndexEntry('sphinx.config', 2, 'index', 'module-sphinx.config', '', '', '')])], + False + ) + + +@pytest.mark.sphinx(freshenv=True) +def test_module_index_not_collapsed(app): + text = (".. py:module:: docutils\n" + ".. py:module:: sphinx\n") + restructuredtext.parse(app, text) + index = PythonModuleIndex(app.env.get_domain('py')) + assert index.generate() == ( + [('d', [IndexEntry('docutils', 0, 'index', 'module-docutils', '', '', '')]), + ('s', [IndexEntry('sphinx', 0, 'index', 'module-sphinx', '', '', '')])], + True + ) diff --git a/tests/test_ext_apidoc.py b/tests/test_ext_apidoc.py index 9fefb4ce92..c6cf43c7e3 100644 --- a/tests/test_ext_apidoc.py +++ b/tests/test_ext_apidoc.py @@ -401,6 +401,21 @@ def test_subpackage_in_toc(make_app, apidoc): assert (outdir / 'parent.child.foo.rst').isfile() +def test_private(tempdir): + (tempdir / 'hello.py').write_text('') + (tempdir / '_world.py').write_text('') + + # without --private option + apidoc_main(['-o', tempdir, tempdir]) + assert (tempdir / 'hello.rst').exists() + assert not (tempdir / '_world.rst').exists() + + # with --private option + apidoc_main(['--private', '-o', tempdir, tempdir]) + assert (tempdir / 'hello.rst').exists() + assert (tempdir / '_world.rst').exists() + + def test_toc_file(tempdir): outdir = path(tempdir) (outdir / 'module').makedirs() diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index aabfc24419..c58fdc0e12 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -14,9 +14,13 @@ import os from unittest.mock import Mock import pytest +from docutils import nodes -from sphinx.ext.autosummary import mangle_signature, import_by_name, extract_summary -from sphinx.testing.util import etree_parse +from sphinx import addnodes +from sphinx.ext.autosummary import ( + autosummary_table, autosummary_toc, mangle_signature, import_by_name, extract_summary +) +from sphinx.testing.util import assert_node, etree_parse from sphinx.util.docutils import new_document html_warnfile = StringIO() @@ -44,11 +48,13 @@ def test_mangle_signature(): (a, b[, c]) :: (a, b[, c]) (a, b[, cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]) :: (a, b[, ...) (a, b='c=d, e=f, g=h', c=3) :: (a[, b, c]) + (a, b="c=d, e=f, g=h", c=3) :: (a[, b, c]) (a, b='c=d, \\'e=f,\\' g=h', c=3) :: (a[, b, c]) (a, b='c=d, ', e='\\\\' g=h, c=3) :: (a[, b, e, c]) (a, b={'c=d, ': 3, '\\\\': 3}) :: (a[, b]) (a=1, b=2, c=3) :: ([a, b, c]) (a=1, b=, c=3) :: ([a, b, c]) + (a=1, b=T(a=1, b=2), c=3) :: ([a, b, c]) (a: int, b: int) -> str :: (a, b) """ @@ -180,6 +186,25 @@ def test_escaping(app, status, warning): @pytest.mark.sphinx('dummy', testroot='ext-autosummary') def test_autosummary_generate(app, status, warning): app.builder.build_all() + + doctree = app.env.get_doctree('index') + assert_node(doctree, (nodes.paragraph, + nodes.paragraph, + addnodes.tabular_col_spec, + autosummary_table, + autosummary_toc)) + assert_node(doctree[3], + [autosummary_table, nodes.table, nodes.tgroup, (nodes.colspec, + nodes.colspec, + [nodes.tbody, (nodes.row, + nodes.row, + nodes.row, + nodes.row)])]) + assert doctree[3][0][0][2][0].astext() == 'autosummary_dummy_module\n\n' + assert doctree[3][0][0][2][1].astext() == 'autosummary_dummy_module.Foo()\n\n' + assert doctree[3][0][0][2][2].astext() == 'autosummary_dummy_module.bar(x[, y])\n\n' + assert doctree[3][0][0][2][3].astext() == 'autosummary_importfail\n\n' + module = (app.srcdir / 'generated' / 'autosummary_dummy_module.rst').text() assert (' .. autosummary::\n' ' \n' diff --git a/tests/test_ext_coverage.py b/tests/test_ext_coverage.py index 73181909d7..8209820a08 100644 --- a/tests/test_ext_coverage.py +++ b/tests/test_ext_coverage.py @@ -45,3 +45,22 @@ def test_build(app, status, warning): assert 'classes' in undoc_py['autodoc_target'] assert 'Class' in undoc_py['autodoc_target']['classes'] assert 'undocmeth' in undoc_py['autodoc_target']['classes']['Class'] + + +@pytest.mark.sphinx('coverage', testroot='ext-coverage') +def test_coverage_ignore_pyobjects(app, status, warning): + app.builder.build_all() + actual = (app.outdir / 'python.txt').text() + expected = '''Undocumented Python objects +=========================== +coverage_not_ignored +-------------------- +Classes: + * Documented -- missing methods: + + - not_ignored1 + - not_ignored2 + * NotIgnored + +''' + assert actual == expected diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index c80b2b7c87..22f8ded6fd 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -196,7 +196,7 @@ def test_Signature_partialmethod(): def test_Signature_annotations(): from typing_test_data import (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, - f11, f12, f13, f14, f15, f16, f17, Node) + f11, f12, f13, f14, f15, f16, f17, f18, Node) # Class annotations sig = inspect.Signature(f0).format_args() @@ -273,6 +273,9 @@ def test_Signature_annotations(): sig = inspect.Signature(f17).format_args() assert sig == '(*, arg3, arg4)' + sig = inspect.Signature(f18).format_args() + assert sig == '(self, arg1: Union[int, Tuple] = 10) -> List[Dict]' + # type hints by string sig = inspect.Signature(Node.children).format_args() if (3, 5, 0) <= sys.version_info < (3, 5, 3): diff --git a/tests/test_util_nodes.py b/tests/test_util_nodes.py index c83fda36f3..1a2ded4477 100644 --- a/tests/test_util_nodes.py +++ b/tests/test_util_nodes.py @@ -17,7 +17,7 @@ from docutils.parsers import rst from docutils.utils import new_document from sphinx.transforms import ApplySourceWorkaround -from sphinx.util.nodes import NodeMatcher, extract_messages, clean_astext +from sphinx.util.nodes import NodeMatcher, extract_messages, clean_astext, split_explicit_title def _transform(doctree): @@ -178,3 +178,18 @@ def test_clean_astext(): node = nodes.paragraph(text='hello world') node += nodes.raw('', 'raw text', format='html') assert 'hello world' == clean_astext(node) + + +@pytest.mark.parametrize( + 'title, expected', + [ + # implicit + ('hello', (False, 'hello', 'hello')), + # explicit + ('hello ', (True, 'hello', 'world')), + # explicit (title having angle brackets) + ('hello ', (True, 'hello ', 'sphinx')), + ] +) +def test_split_explicit_target(title, expected): + assert expected == split_explicit_title(title) diff --git a/tests/typing_test_data.py b/tests/typing_test_data.py index 2e0e27ced3..e7289e8005 100644 --- a/tests/typing_test_data.py +++ b/tests/typing_test_data.py @@ -1,5 +1,5 @@ from numbers import Integral -from typing import Any, List, TypeVar, Union, Callable, Tuple, Optional +from typing import Any, Dict, List, TypeVar, Union, Callable, Tuple, Optional def f0(x: int, y: Integral) -> None: @@ -88,6 +88,10 @@ def f17(*, arg3, arg4): pass +def f18(self, arg1: Union[int, Tuple] = 10) -> List[Dict]: + pass + + class Node: def __init__(self, parent: Optional['Node']) -> None: pass diff --git a/utils/doclinter.py b/utils/doclinter.py index 3f711bfa58..52b2fe892b 100644 --- a/utils/doclinter.py +++ b/utils/doclinter.py @@ -14,7 +14,10 @@ import sys from typing import List -MAX_LINE_LENGTH = 100 +MAX_LINE_LENGTH = 85 +LONG_INTERPRETED_TEXT = re.compile(r'^\s*\W*(:(\w+:)+)?`.*`\W*$') +CODE_BLOCK_DIRECTIVE = re.compile(r'^(\s*)\.\. code-block::') +LEADING_SPACES = re.compile(r'^(\s*)') def lint(path: str) -> int: @@ -22,13 +25,28 @@ def lint(path: str) -> int: document = f.readlines() errors = 0 + in_code_block = False + code_block_depth = 0 for i, line in enumerate(document): if line.endswith(' '): print('%s:%d: the line ends with whitespace.' % (path, i + 1)) errors += 1 - if len(line) > MAX_LINE_LENGTH: + matched = CODE_BLOCK_DIRECTIVE.match(line) + if matched: + in_code_block = True + code_block_depth = len(matched.group(1)) + elif in_code_block: + if line.strip() == '': + pass + else: + spaces = LEADING_SPACES.match(line).group(1) + if len(spaces) < code_block_depth: + in_code_block = False + elif LONG_INTERPRETED_TEXT.match(line): + pass + elif len(line) > MAX_LINE_LENGTH: if re.match(r'^\s*\.\. ', line): # ignore directives and hyperlink targets pass @@ -42,12 +60,15 @@ def lint(path: str) -> int: def main(args: List[str]) -> int: errors = 0 - for directory in args: - for root, dirs, files in os.walk(directory): - for filename in files: - if filename.endswith('.rst'): - path = os.path.join(root, filename) - errors += lint(path) + for path in args: + if os.path.isfile(path): + errors += lint(path) + elif os.path.isdir(path): + for root, dirs, files in os.walk(path): + for filename in files: + if filename.endswith('.rst'): + path = os.path.join(root, filename) + errors += lint(path) if errors: return 1