diff --git a/CHANGES b/CHANGES index f09413c62..9fd548371 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,8 @@ Features added -------------- * #5124: graphviz: ``:graphviz_dot:`` option is renamed to ``:layout:`` +* #1464: html: emit a warning if :confval:`html_static_path` and + :confval:`html_extra_path` directories are inside output directory Bugs fixed ---------- diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 147ac14a9..5772d1cb0 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -1151,17 +1151,25 @@ def validate_math_renderer(app: Sphinx) -> None: def validate_html_extra_path(app: Sphinx, config: Config) -> None: """Check html_extra_paths setting.""" for entry in config.html_extra_path[:]: - if not path.exists(path.join(app.confdir, entry)): + extra_path = path.normpath(path.join(app.confdir, entry)) + if not path.exists(extra_path): logger.warning(__('html_extra_path entry %r does not exist'), entry) config.html_extra_path.remove(entry) + elif path.commonpath([app.outdir, extra_path]) == app.outdir: + logger.warning(__('html_extra_path entry %r is placed inside outdir'), entry) + config.html_extra_path.remove(entry) def validate_html_static_path(app: Sphinx, config: Config) -> None: """Check html_static_paths setting.""" for entry in config.html_static_path[:]: - if not path.exists(path.join(app.confdir, entry)): + static_path = path.normpath(path.join(app.confdir, entry)) + if not path.exists(static_path): logger.warning(__('html_static_path entry %r does not exist'), entry) config.html_static_path.remove(entry) + elif path.commonpath([app.outdir, static_path]) == app.outdir: + logger.warning(__('html_static_path entry %r is placed inside outdir'), entry) + config.html_static_path.remove(entry) def validate_html_logo(app: Sphinx, config: Config) -> None: diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 677ca9de0..352166d94 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -16,6 +16,7 @@ from itertools import cycle, chain import pytest from html5lib import HTMLParser +from sphinx.builders.html import validate_html_extra_path, validate_html_static_path from sphinx.errors import ConfigError from sphinx.testing.util import strip_escseq from sphinx.util import docutils @@ -1496,3 +1497,29 @@ def test_html_pygments_style_manually(app): def test_html_pygments_for_classic_theme(app): style = app.builder.highlighter.formatter_args.get('style') assert style.__name__ == 'SphinxStyle' + + +@pytest.mark.sphinx(testroot='basic', srcdir='validate_html_extra_path') +def test_validate_html_extra_path(app): + (app.confdir / '_static').makedirs() + app.config.html_extra_path = [ + '/path/to/not_found', # not found + '_static', + app.outdir, # outdir + app.outdir / '_static', # inside outdir + ] + validate_html_extra_path(app, app.config) + assert app.config.html_extra_path == ['_static'] + + +@pytest.mark.sphinx(testroot='basic', srcdir='validate_html_static_path') +def test_validate_html_static_path(app): + (app.confdir / '_static').makedirs() + app.config.html_static_path = [ + '/path/to/not_found', # not found + '_static', + app.outdir, # outdir + app.outdir / '_static', # inside outdir + ] + validate_html_static_path(app, app.config) + assert app.config.html_static_path == ['_static']