Merge pull request #6022 from tk0miya/5196_linkcheck_should_check_remote_image

Close #5196: linkcheck also checks remote images exist
This commit is contained in:
Takeshi KOMIYA 2019-02-11 02:05:14 +09:00 committed by GitHub
commit 8812131a57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 11 deletions

View File

@ -177,6 +177,7 @@ Features added
* #6016: HTML search: A placeholder for the search summary prevents search * #6016: HTML search: A placeholder for the search summary prevents search
result links from changing their position when the search terminates. This result links from changing their position when the search terminates. This
makes navigating search results easier. makes navigating search results easier.
* #5196: linkcheck also checks remote images exist
Bugs fixed Bugs fixed
---------- ----------

View File

@ -25,7 +25,7 @@ from sphinx.util import encode_uri, requests, logging
from sphinx.util.console import ( # type: ignore from sphinx.util.console import ( # type: ignore
purple, red, darkgreen, darkgray, darkred, turquoise purple, red, darkgreen, darkgray, darkred, turquoise
) )
from sphinx.util.nodes import traverse_parent from sphinx.util.nodes import get_node_line
from sphinx.util.requests import is_ssl_error from sphinx.util.requests import is_ssl_error
if False: if False:
@ -271,17 +271,24 @@ class CheckExternalLinksBuilder(Builder):
# type: (str, nodes.Node) -> None # type: (str, nodes.Node) -> None
logger.info('') logger.info('')
n = 0 n = 0
for node in doctree.traverse(nodes.reference):
if 'refuri' not in node: # reference nodes
for refnode in doctree.traverse(nodes.reference):
if 'refuri' not in refnode:
continue continue
uri = node['refuri'] uri = refnode['refuri']
lineno = None lineno = get_node_line(refnode)
for parent in traverse_parent(node):
if parent.line:
lineno = parent.line
break
self.wqueue.put((uri, docname, lineno), False) self.wqueue.put((uri, docname, lineno), False)
n += 1 n += 1
# image nodes
for imgnode in doctree.traverse(nodes.image):
uri = imgnode['candidates'].get('?')
if uri and '://' in uri:
lineno = get_node_line(imgnode)
self.wqueue.put((uri, docname, lineno), False)
n += 1
done = 0 done = 0
while done < n: while done < n:
self.process_result(self.rqueue.get()) self.process_result(self.rqueue.get())

View File

@ -285,6 +285,14 @@ def find_source_node(node):
return None return None
def get_node_line(node):
# type: (nodes.Element) -> int
for pnode in traverse_parent(node):
if pnode.line:
return pnode.line
return None
def traverse_parent(node, cls=None): def traverse_parent(node, cls=None):
# type: (nodes.Element, Any) -> Iterable[nodes.Element] # type: (nodes.Element, Any) -> Iterable[nodes.Element]
while node: while node:

View File

@ -11,3 +11,6 @@ Some additional anchors to exercise ignore code
* `Example Bar invalid <http://example.com/#top>`_ * `Example Bar invalid <http://example.com/#top>`_
* `Example anchor invalid <http://www.sphinx-doc.org/en/1.7/intro.html#does-not-exist>`_ * `Example anchor invalid <http://www.sphinx-doc.org/en/1.7/intro.html#does-not-exist>`_
* `Complete nonsense <https://localhost:7777/doesnotexist>`_ * `Complete nonsense <https://localhost:7777/doesnotexist>`_
.. image:: http://example.com/image.png
.. figure:: http://example.com/image2.png

View File

@ -24,7 +24,10 @@ def test_defaults(app, status, warning):
assert "Anchor 'does-not-exist' not found" in content assert "Anchor 'does-not-exist' not found" in content
# looking for non-existent URL should fail # looking for non-existent URL should fail
assert " Max retries exceeded with url: /doesnotexist" in content assert " Max retries exceeded with url: /doesnotexist" in content
assert len(content.splitlines()) == 3 # images should fail
assert "Not Found for url: http://example.com/image.png" in content
assert "Not Found for url: http://example.com/image2.png" in content
assert len(content.splitlines()) == 5
@pytest.mark.sphinx( @pytest.mark.sphinx(
@ -32,7 +35,9 @@ def test_defaults(app, status, warning):
confoverrides={'linkcheck_anchors_ignore': ["^!", "^top$"], confoverrides={'linkcheck_anchors_ignore': ["^!", "^top$"],
'linkcheck_ignore': [ 'linkcheck_ignore': [
'https://localhost:7777/doesnotexist', 'https://localhost:7777/doesnotexist',
'http://www.sphinx-doc.org/en/1.7/intro.html#'] 'http://www.sphinx-doc.org/en/1.7/intro.html#',
'http://example.com/image.png',
'http://example.com/image2.png']
}) })
def test_anchors_ignored(app, status, warning): def test_anchors_ignored(app, status, warning):
app.builder.build_all() app.builder.build_all()