diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 000000000..3012267c2 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,48 @@ +environment: + global: + TEST: -v --durations 25 + PYTHONFAULTHANDLER: x + PYTHONWARNINGS: all + + matrix: + - PYTHON: 27 + DOCUTILS: 0.12 + TEST_IGNORE: --ignore py35 + - PYTHON: 27 + DOCUTILS: 0.13.1 + TEST_IGNORE: --ignore py35 + - PYTHON: 36 + DOCUTILS: 0.13.1 + - PYTHON: 36-x64 + DOCUTILS: 0.13.1 + +install: + - C:\Python%PYTHON%\python.exe -m pip install -U pip setuptools + - C:\Python%PYTHON%\python.exe -m pip install docutils==%DOCUTILS% + - C:\Python%PYTHON%\python.exe -m pip install -r test-reqs.txt + +# No automatic build, just run python tests +build: off + +# Update build information before testing, no warnings during this step +before_test: + - ps: | + $py_warnings = $env:PYTHONWARNINGS + $env:PYTHONWARNINGS = 'ignore' + Update-AppveyorBuild -Version ((& "C:\Python$($env:PYTHON)\python.exe" -m sphinx --version).Split(' ')[2]) + $env:PYTHONWARNINGS = $py_warnings + +test_script: + - ps: | + Push-Location tests + $test_ignore = $env:TEST_IGNORE + if (-not $test_ignore) { $test_ignore = '' } + $tests = $env:TEST + if (-not $tests) { $tests = '' } + & "C:\Python$($env:PYTHON)\python.exe" run.py $test_ignore.Split(' ') --junitxml .junit.xml $tests.Split(' ') + Pop-Location + if ($LastExitCode -eq 1) { Write-Host "Test Failures Occurred, leaving for test result parsing" } + elseif ($LastExitCode -ne 0) { Write-Host "Other Error Occurred, aborting"; exit $LastExitCode } + +after_test: + - ps: (New-Object System.Net.WebClient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path (Join-Path tests .junit.xml))) diff --git a/CHANGES b/CHANGES index 8a44dbe72..95bf68d1d 100644 --- a/CHANGES +++ b/CHANGES @@ -85,6 +85,16 @@ Bugs fixed name contains spaces * #3850: Fix color handling in make mode's help command * #3865: use of self.env.warn in sphinx extension fails +* #3824: production lists apply smart quotes transform since Sphinx 1.6.1 +* latex: fix ``\sphinxbfcode`` swallows initial space of argument +* #3878: Quotes in auto-documented class attributes should be straight quotes + in PDF output +* #3881: LaTeX figure floated to next page sometimes leaves extra vertical + whitespace +* #3885: duplicated footnotes raises IndexError +* #3873: Failure of deprecation warning mechanism of + ``sphinx.util.compat.Directive`` +* #3874: Bogus warnings for "citation not referenced" for cross-file citations Testing -------- @@ -300,6 +310,8 @@ Bugs fixed * #3661: sphinx-build crashes on parallel build * #3669: gettext builder fails with "ValueError: substring not found" * #3660: Sphinx always depends on sphinxcontrib-websupport and its dependencies +* #3472: smart quotes getting wrong in latex (at least with list of strings via + autoattribute) (refs: #3345, #3666) 1.6b3 diff --git a/doc/ext/math.rst b/doc/ext/math.rst index dace54964..54d77ed6c 100644 --- a/doc/ext/math.rst +++ b/doc/ext/math.rst @@ -1,5 +1,7 @@ .. highlight:: rest +.. _math-support: + Math support in Sphinx ====================== @@ -231,10 +233,14 @@ Sphinx. The path to the JavaScript file to include in the HTML files in order to load MathJax. - The default is the ``http://`` URL that loads the JS files from the `MathJax - CDN `_. If you want MathJax to - be available offline, you have to download it and set this value to a - different path. + The default is the ``https://`` URL that loads the JS files from the + `cdnjs`__ Content Delivery Network. See the `MathJax Getting Started + page`__ for details. If you want MathJax to be available offline, you have + to download it and set this value to a different path. + + __ https://cdjns.com + + __ http://docs.mathjax.org/en/latest/start.html The path can be absolute or relative; if it is relative, it is relative to the ``_static`` directory of the built docs. diff --git a/doc/markup/misc.rst b/doc/markup/misc.rst index c4b64e39c..35ed6375d 100644 --- a/doc/markup/misc.rst +++ b/doc/markup/misc.rst @@ -210,7 +210,17 @@ Including content based on tags Tables ------ -Use :ref:`standard reStructuredText tables `. They work fine in +Use :ref:`reStructuredText tables `, i.e. either + +- grid table syntax (:duref:`ref `), +- simple table syntax (:duref:`ref `), +- :dudir:`csv-table` syntax, +- or :dudir:`list-table` syntax. + +The :dudir:`table` directive serves as optional wrapper of the *grid* and +*simple* syntaxes. + +They work fine in HTML output, however there are some gotchas when using tables in LaTeX: the column width is hard to determine correctly automatically. For this reason, the following directive exists: @@ -313,6 +323,11 @@ following directive exists: Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``, ``Y{f}`` and tabulary's columns. +Math +---- + +See :ref:`math-support`. + .. rubric:: Footnotes .. [#] For most builders name and format are the same. At the moment only diff --git a/doc/rest.rst b/doc/rest.rst index f39ade669..fbc3f2254 100644 --- a/doc/rest.rst +++ b/doc/rest.rst @@ -159,7 +159,7 @@ rendered as "The next paragraph is a code sample:". Tables ------ -Two forms of tables are supported. For *grid tables* (:duref:`ref +For *grid tables* (:duref:`ref `), you have to "paint" the cell grid yourself. They look like this:: @@ -173,7 +173,7 @@ this:: +------------------------+------------+----------+----------+ *Simple tables* (:duref:`ref `) are easier to write, but -limited: they must contain more than one row, and the first column cannot +limited: they must contain more than one row, and the first column cells cannot contain multiple lines. They look like this:: ===== ===== ======= @@ -185,6 +185,8 @@ contain multiple lines. They look like this:: True True True ===== ===== ======= +Two more syntaxes are supported: *CSV tables* and *List tables*. They use an +*explicit markup block*, see `Directives`_ section. Hyperlinks ---------- diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 26645eed2..bfaa57c4f 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -492,8 +492,8 @@ class StandardDomain(Domain): initial_data = { 'progoptions': {}, # (program, name) -> docname, labelid 'objects': {}, # (type, name) -> docname, labelid - 'citations': {}, # name -> docname, labelid, lineno - 'citation_refs': {}, # labelid -> list of docnames + 'citations': {}, # citation_name -> docname, labelid, lineno + 'citation_refs': {}, # citation_name -> list of docnames 'labels': { # labelname -> docname, labelid, sectionname 'genindex': ('genindex', '', l_('Index')), 'modindex': ('py-modindex', '', l_('Module Index')), @@ -588,12 +588,11 @@ class StandardDomain(Domain): def note_citation_refs(self, env, docname, document): # type: (BuildEnvironment, unicode, nodes.Node) -> None - for name, refs in iteritems(document.citation_refs): - for ref in refs: - labelid = ref.get('refid') - if labelid: - citation_refs = self.data['citation_refs'].setdefault(labelid, []) - citation_refs.append(docname) + for node in document.traverse(addnodes.pending_xref): + if node['refdomain'] == 'std' and node['reftype'] == 'citation': + label = node['reftarget'] + citation_refs = self.data['citation_refs'].setdefault(label, []) + citation_refs.append(docname) def note_labels(self, env, docname, document): # type: (BuildEnvironment, unicode, nodes.Node) -> None @@ -638,7 +637,7 @@ class StandardDomain(Domain): def check_consistency(self): # type: () -> None for name, (docname, labelid, lineno) in iteritems(self.data['citations']): - if labelid not in self.data['citation_refs']: + if name not in self.data['citation_refs']: logger.warning('Citation [%s] is not referenced.', name, type='ref', subtype='citation', location=(docname, lineno)) diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty index 5295cfe48..f305409be 100644 --- a/sphinx/texinputs/sphinx.sty +++ b/sphinx/texinputs/sphinx.sty @@ -6,7 +6,7 @@ % \NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesPackage{sphinx}[2017/05/08 v1.6 LaTeX package (Sphinx markup)] +\ProvidesPackage{sphinx}[2017/06/17 v1.6.3 LaTeX package (Sphinx markup)] % provides \ltx@ifundefined % (many packages load ltxcmds: graphicx does for pdftex and lualatex but @@ -1392,7 +1392,7 @@ \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1 }}} \def\sphinx@literal@nolig@list {\do\`\do\<\do\>\do\'\do\-}% -\protected\def\sphinxbfcode#1{\sphinxcode{\bfseries#1}} +\protected\def\sphinxbfcode#1{\sphinxcode{\bfseries{}#1}} \protected\def\sphinxemail#1{\textsf{#1}} \protected\def\sphinxtablecontinued#1{\textsf{#1}} \protected\def\sphinxtitleref#1{\emph{#1}} diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py index 1e7f3c41e..a257f19d1 100644 --- a/sphinx/transforms/__init__.py +++ b/sphinx/transforms/__init__.py @@ -283,13 +283,16 @@ class ExtraTranslatableNodes(SphinxTransform): class UnreferencedFootnotesDetector(SphinxTransform): """ - detect unreferenced footnotes and citations, and emit warnings + detect unreferenced footnotes and emit warnings """ default_priority = 200 def apply(self): for node in self.document.footnotes: - if node['names'][0] not in self.document.footnote_refs: + if node['names'] == []: + # footnote having duplicated number. It is already warned at parser. + pass + elif node['names'][0] not in self.document.footnote_refs: logger.warning('Footnote [%s] is not referenced.', node['names'][0], type='ref', subtype='footnote', location=node) @@ -345,13 +348,17 @@ class SphinxSmartQuotes(SmartQuotes): for txtnode in txtnodes: nodetype = texttype[isinstance(txtnode.parent, (nodes.literal, - nodes.literal_block, addnodes.literal_emphasis, addnodes.literal_strong, - addnodes.desc_signature, - addnodes.productionlist, - addnodes.desc_optional, + addnodes.desc_addname, + addnodes.desc_annotation, addnodes.desc_name, + addnodes.desc_optional, + addnodes.desc_parameter, + addnodes.desc_parameterlist, + addnodes.desc_signature_line, + addnodes.desc_type, + addnodes.production, nodes.math, nodes.image, nodes.raw, diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py new file mode 100644 index 000000000..20975f83d --- /dev/null +++ b/sphinx/util/compat.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" + sphinx.util.compat + ~~~~~~~~~~~~~~~~~~ + + Stuff for docutils compatibility. + + :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" +from __future__ import absolute_import + +import sys +import warnings +from distutils.version import LooseVersion + +from docutils.parsers.rst import Directive # noqa +from docutils import __version__ as _du_version + +from sphinx.deprecation import RemovedInSphinx17Warning + +docutils_version = tuple(LooseVersion(_du_version).version)[:2] + +if False: + # For type annotation + from typing import Any, Dict # NOQA + + +class _DeprecationWrapper(object): + def __init__(self, mod, deprecated): + # type: (Any, Dict) -> None + self._mod = mod + self._deprecated = deprecated + + def __getattr__(self, attr): + # type: (str) -> Any + if attr in self._deprecated: + warnings.warn("sphinx.util.compat.%s is deprecated and will be " + "removed in Sphinx 1.7, please use the standard " + "library version instead." % attr, + RemovedInSphinx17Warning) + return self._deprecated[attr] + return getattr(self._mod, attr) + + +sys.modules[__name__] = _DeprecationWrapper(sys.modules[__name__], dict( # type: ignore + docutils_version = docutils_version, + Directive = Directive, +)) diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 8d0b7759b..10683d449 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -1229,7 +1229,7 @@ class LaTeXTranslator(nodes.NodeVisitor): def visit_desc_annotation(self, node): # type: (nodes.Node) -> None - self.body.append(r'\sphinxstrong{') + self.body.append(r'\sphinxbfcode{') def depart_desc_annotation(self, node): # type: (nodes.Node) -> None @@ -1811,7 +1811,7 @@ class LaTeXTranslator(nodes.NodeVisitor): # TODO non vertical space for other alignments. align = '\\begin{flush%s}' % node.attributes['align'] align_end = '\\end{flush%s}' % node.attributes['align'] - self.body.append('\\begin{figure}[%s]%s\n' % ( + self.body.append('\n\\begin{figure}[%s]%s\n' % ( self.elements['figure_align'], align)) if any(isinstance(child, nodes.caption) for child in node): self.body.append('\\capstart\n') diff --git a/tests/test_build.py b/tests/test_build.py index 30bbfa14a..185b5cda4 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -15,6 +15,7 @@ import mock import pytest from textwrap import dedent from sphinx.errors import SphinxError +import sys from sphinx.testing.path import path @@ -31,6 +32,11 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir): # If supported, build in a non-ASCII source dir test_name = u'\u65e5\u672c\u8a9e' basedir = sphinx_test_tempdir / request.node.originalname + # Windows with versions prior to 3.2 (I think) doesn't support unicode on system path + # so we force a non-unicode path in that case + if sys.platform == "win32" and \ + not (sys.version_info.major >= 3 and sys.version_info.minor >= 2): + return basedir / 'all' try: srcdir = basedir / test_name if not srcdir.exists(): @@ -64,6 +70,7 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir): ) @mock.patch('sphinx.builders.linkcheck.requests.head', side_effect=request_session_head) +@pytest.mark.xfail(sys.platform == 'win32', reason="Not working on windows") def test_build_all(requests_head, make_app, nonascii_srcdir, buildername): app = make_app(buildername, srcdir=nonascii_srcdir) app.build() diff --git a/tests/test_build_html.py b/tests/test_build_html.py index b2533629d..ceeb5f01c 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -147,7 +147,7 @@ def check_extra_entries(outdir): @pytest.mark.sphinx('html', testroot='warnings') def test_html_warnings(app, warning): app.build() - html_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/')) + html_warnings = strip_escseq(re.sub(re.escape(os.sep) + '{1,2}', '/', warning.getvalue())) html_warnings_exp = HTML_WARNINGS % { 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(html_warnings_exp + '$', html_warnings), \ @@ -1167,6 +1167,7 @@ def test_html_entity(app): @pytest.mark.sphinx('html', testroot='basic') +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_html_inventory(app): app.builder.build_all() with open(app.outdir / 'objects.inv', 'rb') as f: diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 441f12d0d..6e2b9b39d 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -155,7 +155,7 @@ def test_writer(app, status, warning): def test_latex_warnings(app, status, warning): app.builder.build_all() - warnings = strip_escseq(warning.getvalue().replace(os.sep, '/')) + warnings = strip_escseq(re.sub(re.escape(os.sep) + '{1,2}', '/', warning.getvalue())) warnings_exp = LATEX_WARNINGS % { 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(warnings_exp + '$', warnings), \ diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index 0676d5dc4..c4238c659 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -37,7 +37,7 @@ if PY3: @pytest.mark.sphinx('texinfo', testroot='warnings', freshenv=True) def test_texinfo_warnings(app, status, warning): app.builder.build_all() - warnings = strip_escseq(warning.getvalue().replace(os.sep, '/')) + warnings = strip_escseq(re.sub(re.escape(os.sep) + '{1,2}', '/', warning.getvalue())) warnings_exp = TEXINFO_WARNINGS % { 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(warnings_exp + '$', warnings), \ diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py index 5f67c5627..548a5d72c 100644 --- a/tests/test_directive_code.py +++ b/tests/test_directive_code.py @@ -10,6 +10,7 @@ """ import pytest +import os from sphinx.config import Config from sphinx.directives.code import LiteralIncludeReader @@ -29,6 +30,7 @@ def literal_inc_path(testroot): return testroot / 'literal.inc' +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader(literal_inc_path): options = {'lineno-match': True} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -38,6 +40,7 @@ def test_LiteralIncludeReader(literal_inc_path): assert reader.lineno_start == 1 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_lineno_start(literal_inc_path): options = {'lineno-start': 5} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -47,6 +50,7 @@ def test_LiteralIncludeReader_lineno_start(literal_inc_path): assert reader.lineno_start == 5 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_pyobject1(literal_inc_path): options = {'lineno-match': True, 'pyobject': 'Foo'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -56,6 +60,7 @@ def test_LiteralIncludeReader_pyobject1(literal_inc_path): assert reader.lineno_start == 6 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_pyobject2(literal_inc_path): options = {'pyobject': 'Bar'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -66,6 +71,7 @@ def test_LiteralIncludeReader_pyobject2(literal_inc_path): assert reader.lineno_start == 1 # no lineno-match +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_pyobject3(literal_inc_path): options = {'pyobject': 'Bar.baz'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -74,6 +80,7 @@ def test_LiteralIncludeReader_pyobject3(literal_inc_path): " pass\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_pyobject_and_lines(literal_inc_path): options = {'pyobject': 'Bar', 'lines': '2-'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -82,6 +89,7 @@ def test_LiteralIncludeReader_pyobject_and_lines(literal_inc_path): " pass\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_lines1(literal_inc_path): options = {'lines': '1-4'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -92,6 +100,7 @@ def test_LiteralIncludeReader_lines1(literal_inc_path): u"foo = \"Including Unicode characters: üöä\"\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_lines2(literal_inc_path): options = {'lines': '1,4,6'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -101,6 +110,7 @@ def test_LiteralIncludeReader_lines2(literal_inc_path): u"class Foo:\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_lines_and_lineno_match1(literal_inc_path): options = {'lines': '4-6', 'lineno-match': True} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -127,6 +137,7 @@ def test_LiteralIncludeReader_lines_and_lineno_match3(literal_inc_path, app, sta content, lines = reader.read() +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_start_at(literal_inc_path): options = {'lineno-match': True, 'start-at': 'Foo', 'end-at': 'Bar'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -138,6 +149,7 @@ def test_LiteralIncludeReader_start_at(literal_inc_path): assert reader.lineno_start == 6 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_start_after(literal_inc_path): options = {'lineno-match': True, 'start-after': 'Foo', 'end-before': 'Bar'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -147,6 +159,7 @@ def test_LiteralIncludeReader_start_after(literal_inc_path): assert reader.lineno_start == 7 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_start_after_and_lines(literal_inc_path): options = {'lineno-match': True, 'lines': '6-', 'start-after': 'coding', 'end-before': 'comment'} @@ -160,6 +173,7 @@ def test_LiteralIncludeReader_start_after_and_lines(literal_inc_path): assert reader.lineno_start == 8 +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_start_at_and_lines(literal_inc_path): options = {'lines': '2, 3, 5', 'start-at': 'foo', 'end-before': '#'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -192,6 +206,7 @@ def test_LiteralIncludeReader_missing_start_and_end(literal_inc_path): content, lines = reader.read() +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_prepend(literal_inc_path): options = {'lines': '1', 'prepend': 'Hello', 'append': 'Sphinx'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) @@ -201,6 +216,7 @@ def test_LiteralIncludeReader_prepend(literal_inc_path): "Sphinx\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_dedent(literal_inc_path): # dedent: 2 options = {'lines': '10-12', 'dedent': 2} @@ -227,6 +243,7 @@ def test_LiteralIncludeReader_dedent(literal_inc_path): "\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_tabwidth(testroot): # tab-width: 4 options = {'tab-width': 4, 'pyobject': 'Qux'} @@ -245,6 +262,7 @@ def test_LiteralIncludeReader_tabwidth(testroot): " pass\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_tabwidth_dedent(testroot): options = {'tab-width': 4, 'dedent': 4, 'pyobject': 'Qux.quux'} reader = LiteralIncludeReader(testroot / 'target.py', options, DUMMY_CONFIG) @@ -253,6 +271,7 @@ def test_LiteralIncludeReader_tabwidth_dedent(testroot): " pass\n") +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_LiteralIncludeReader_diff(testroot, literal_inc_path): options = {'diff': testroot / 'literal-diff.inc'} reader = LiteralIncludeReader(literal_inc_path, options, DUMMY_CONFIG) diff --git a/tests/test_docutilsconf.py b/tests/test_docutilsconf.py index da86e9312..fd5cf7a61 100644 --- a/tests/test_docutilsconf.py +++ b/tests/test_docutilsconf.py @@ -10,6 +10,7 @@ """ import re +import sys import pytest from sphinx.testing.path import path @@ -71,6 +72,9 @@ def test_texinfo(app, status, warning): @pytest.mark.sphinx('html', testroot='docutilsconf', docutilsconf='[general]\nsource_link=true\n') +@pytest.mark.skip(sys.platform == "win32" and \ + not (sys.version_info.major >= 3 and sys.version_info.minor >= 2), + reason="Python < 3.2 on Win32 doesn't handle non-ASCII paths right") def test_docutils_source_link_with_nonascii_file(app, status, warning): srcdir = path(app.srcdir) mb_name = u'\u65e5\u672c\u8a9e' diff --git a/tests/test_ext_imgconverter.py b/tests/test_ext_imgconverter.py index 9baf0eb2a..cc84001df 100644 --- a/tests/test_ext_imgconverter.py +++ b/tests/test_ext_imgconverter.py @@ -10,9 +10,11 @@ """ import pytest +import os @pytest.mark.sphinx('latex', testroot='ext-imgconverter') +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_ext_imgconverter(app, status, warning): app.builder.build_all() diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py index 47f2029dc..4965108ef 100644 --- a/tests/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx.py @@ -16,6 +16,7 @@ import mock import pytest import requests from io import BytesIO +import os from sphinx import addnodes from sphinx.ext.intersphinx import setup as intersphinx_setup @@ -86,6 +87,7 @@ def test_fetch_inventory_redirection(_read_from_url, InventoryFile, app, status, assert InventoryFile.load.call_args[0][1] == 'http://hostname/' +@pytest.mark.xfail(os.name != 'posix', reason="Path separator mismatch issue") def test_missing_reference(tempdir, app, status, warning): inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) diff --git a/tests/test_intl.py b/tests/test_intl.py index 5a6c1c9af..413276e44 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -152,6 +152,7 @@ def test_text_warning_node(app): @sphinx_intl @pytest.mark.sphinx('text') @pytest.mark.test_params(shared_result='test_intl_basic') +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_text_title_underline(app): app.build() # --- simple translation; check title underlines @@ -1084,6 +1085,7 @@ def test_text_references(app, warning): srcdir='test_intl_images', confoverrides={'language': 'xx'} ) +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_image_glob_intl(app): app.build() # index.rst @@ -1131,6 +1133,7 @@ def test_image_glob_intl(app): 'figure_language_filename': u'{root}{ext}.{language}', } ) +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_image_glob_intl_using_figure_language_filename(app): app.build() # index.rst diff --git a/tests/test_util_i18n.py b/tests/test_util_i18n.py index a155afe35..53e0e4cf1 100644 --- a/tests/test_util_i18n.py +++ b/tests/test_util_i18n.py @@ -186,6 +186,7 @@ def test_format_date(): assert i18n.format_date(format, date=date) == 'Feb 7, 2016' +@pytest.mark.xfail(os.name != 'posix', reason="Path separators don't match on windows") def test_get_filename_for_language(app): # language is None app.env.config.language = None diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py index dfe40fea4..7ca7bd655 100644 --- a/tests/test_util_logging.py +++ b/tests/test_util_logging.py @@ -22,6 +22,8 @@ from sphinx.util.parallel import ParallelTasks import pytest from sphinx.testing.util import strip_escseq +import os + def test_info_and_warning(app, status, warning): app.verbosity = 2 @@ -241,6 +243,7 @@ def test_colored_logs(app, status, warning): assert colorize('red', 'message8') in status.getvalue() +@pytest.mark.xfail(os.name != 'posix', reason="Not working on windows") def test_logging_in_ParallelTasks(app, status, warning): logging.setup(app, status, warning) logger = logging.getLogger(__name__)