diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py index 3b51469d1..06cbfa026 100644 --- a/sphinx/apidoc.py +++ b/sphinx/apidoc.py @@ -16,6 +16,7 @@ """ from __future__ import print_function +import glob import os import sys import optparse @@ -194,7 +195,17 @@ def shall_skip(module, opts): # skip it if there is nothing (or just \n or \r\n) in the file if path.exists(module) and path.getsize(module) <= 2: - return True + skip = True + if os.path.basename(module) == '__init__.py': + pattern = path.join(path.dirname(module), '*.py') + # We only want to skip packages if they do not contain any + # .py files other than __init__.py. + other_modules = list(glob.glob(pattern)) + other_modules.remove(module) + skip = not other_modules + + if skip: + return True # skip if it has a "private" name and this is selected filename = path.basename(module) diff --git a/tests/roots/test-apidoc-pep420/a/b/e/__init__.py b/tests/roots/test-apidoc-pep420/a/b/e/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/roots/test-apidoc-pep420/a/b/e/f.py b/tests/roots/test-apidoc-pep420/a/b/e/f.py new file mode 100644 index 000000000..a09affe86 --- /dev/null +++ b/tests/roots/test-apidoc-pep420/a/b/e/f.py @@ -0,0 +1 @@ +"Module f" diff --git a/tests/test_apidoc.py b/tests/test_apidoc.py index f5037ab71..e7f986df3 100644 --- a/tests/test_apidoc.py +++ b/tests/test_apidoc.py @@ -67,6 +67,7 @@ def test_pep_0420_enabled(make_app, apidoc): outdir = apidoc.outdir assert (outdir / 'conf.py').isfile() assert (outdir / 'a.b.c.rst').isfile() + assert (outdir / 'a.b.e.rst').isfile() assert (outdir / 'a.b.x.rst').isfile() with open(outdir / 'a.b.c.rst') as f: @@ -74,6 +75,10 @@ def test_pep_0420_enabled(make_app, apidoc): assert "automodule:: a.b.c.d\n" in rst assert "automodule:: a.b.c\n" in rst + with open(outdir / 'a.b.e.rst') as f: + rst = f.read() + assert "automodule:: a.b.e.f\n" in rst + with open(outdir / 'a.b.x.rst') as f: rst = f.read() assert "automodule:: a.b.x.y\n" in rst @@ -86,12 +91,67 @@ def test_pep_0420_enabled(make_app, apidoc): builddir = outdir / '_build' / 'text' assert (builddir / 'a.b.c.txt').isfile() + assert (builddir / 'a.b.e.txt').isfile() assert (builddir / 'a.b.x.txt').isfile() with open(builddir / 'a.b.c.txt') as f: txt = f.read() assert "a.b.c package\n" in txt + with open(builddir / 'a.b.e.txt') as f: + txt = f.read() + assert "a.b.e.f module\n" in txt + + with open(builddir / 'a.b.x.txt') as f: + txt = f.read() + assert "a.b.x namespace\n" in txt + + +@pytest.mark.apidoc( + coderoot='test-apidoc-pep420', + options=["--implicit-namespaces", "--separate"], +) +def test_pep_0420_enabled_separate(make_app, apidoc): + outdir = apidoc.outdir + assert (outdir / 'conf.py').isfile() + assert (outdir / 'a.b.c.rst').isfile() + assert (outdir / 'a.b.e.rst').isfile() + assert (outdir / 'a.b.e.f.rst').isfile() + assert (outdir / 'a.b.x.rst').isfile() + assert (outdir / 'a.b.x.y.rst').isfile() + + with open(outdir / 'a.b.c.rst') as f: + rst = f.read() + assert ".. toctree::\n\n a.b.c.d\n" in rst + + with open(outdir / 'a.b.e.rst') as f: + rst = f.read() + assert ".. toctree::\n\n a.b.e.f\n" in rst + + with open(outdir / 'a.b.x.rst') as f: + rst = f.read() + assert ".. toctree::\n\n a.b.x.y\n" in rst + + app = make_app('text', srcdir=outdir) + app.build() + print(app._status.getvalue()) + print(app._warning.getvalue()) + + builddir = outdir / '_build' / 'text' + assert (builddir / 'a.b.c.txt').isfile() + assert (builddir / 'a.b.e.txt').isfile() + assert (builddir / 'a.b.e.f.txt').isfile() + assert (builddir / 'a.b.x.txt').isfile() + assert (builddir / 'a.b.x.y.txt').isfile() + + with open(builddir / 'a.b.c.txt') as f: + txt = f.read() + assert "a.b.c package\n" in txt + + with open(builddir / 'a.b.e.f.txt') as f: + txt = f.read() + assert "a.b.e.f module\n" in txt + with open(builddir / 'a.b.x.txt') as f: txt = f.read() assert "a.b.x namespace\n" in txt