Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit da3eb6e

Browse files
committed
Ensure allowed-package-names actually works.
As it was, it could not handle lists correctly, and even single strings were ignored further down.
1 parent 4c8e33c commit da3eb6e

12 files changed

+174
-9
lines changed

sphinx_automodapi/automodapi.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def automodapi_replace(sourcestr, app, dotoctree=True, docname=None,
256256
elif opname == 'no-heading':
257257
top_head = False
258258
elif opname == 'allowed-package-names':
259-
allowedpkgnms.append(args.strip())
259+
allowedpkgnms.extend(arg.strip() for arg in args.split(','))
260260
elif opname == 'inherited-members':
261261
inherited_members = True
262262
elif opname == 'no-inherited-members':
@@ -271,8 +271,8 @@ def automodapi_replace(sourcestr, app, dotoctree=True, docname=None,
271271
allowedpkgnms = ''
272272
onlylocals = True
273273
else:
274-
allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms)
275274
onlylocals = allowedpkgnms
275+
allowedpkgnms = ':allowed-package-names: ' + ','.join(allowedpkgnms)
276276

277277
# get the two heading chars
278278
hds = hds.strip()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Documenting a module with classes, functions, and variables that are
2+
imported from other files, but where only some of those are allowed.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.. automodapi:: sphinx_automodapi.tests.example_module
2+
:allowed-package-names: sphinx_automodapi.tests.example_module.classes
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Egg
2+
===
3+
4+
.. currentmodule:: sphinx_automodapi.tests.example_module
5+
6+
.. autoclass:: Egg
7+
:show-inheritance:
8+
9+
.. rubric:: Attributes Summary
10+
11+
.. autosummary::
12+
13+
~Egg.weight
14+
15+
.. rubric:: Methods Summary
16+
17+
.. autosummary::
18+
19+
~Egg.buy
20+
~Egg.eat
21+
22+
.. rubric:: Attributes Documentation
23+
24+
.. autoattribute:: weight
25+
26+
.. rubric:: Methods Documentation
27+
28+
.. automethod:: buy
29+
.. automethod:: eat
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Spam
2+
====
3+
4+
.. currentmodule:: sphinx_automodapi.tests.example_module
5+
6+
.. autoclass:: Spam
7+
:show-inheritance:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
sphinx_automodapi.tests.example_module Package
3+
----------------------------------------------
4+
5+
.. automodule:: sphinx_automodapi.tests.example_module
6+
7+
Classes
8+
^^^^^^^
9+
10+
.. automodsumm:: sphinx_automodapi.tests.example_module
11+
:classes-only:
12+
:toctree: api
13+
:allowed-package-names: sphinx_automodapi.tests.example_module.classes
14+
15+
Class Inheritance Diagram
16+
^^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
.. automod-diagram:: sphinx_automodapi.tests.example_module
19+
:private-bases:
20+
:parts: 1
21+
:allowed-package-names: sphinx_automodapi.tests.example_module.classes
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. currentmodule:: sphinx_automodapi.tests.example_module
2+
3+
.. autosummary::
4+
:toctree: api
5+
6+
Egg
7+
Spam
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""
2+
A collection of useful classes and functions
3+
"""
4+
from collections import OrderedDict
5+
6+
7+
def add(a, b):
8+
"""
9+
Add two numbers
10+
"""
11+
return a + b
12+
13+
14+
class MixedSpam(OrderedDict):
15+
"""
16+
Special spam
17+
"""
18+
19+
def eat(self, time):
20+
"""
21+
Eat special spam in the required time.
22+
"""
23+
pass

sphinx_automodapi/tests/test_automodsumm.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from copy import copy
55

6+
import pytest
67
from docutils.parsers.rst import directives, roles
78

89
from . import cython_testpackage # noqa
@@ -107,6 +108,54 @@ def test_too_many_options(tmpdir, capsys):
107108
"classes-only, and variables-only. Skipping this directive." in stderr)
108109

109110

111+
ORDEREDDICT_RST = """
112+
:orphan:
113+
114+
OrderedDict
115+
===========
116+
117+
.. currentmodule:: sphinx_automodapi.tests.example_module.noall
118+
119+
.. autoclass:: OrderedDict
120+
:show-inheritance:
121+
""".strip()
122+
123+
124+
@pytest.mark.parametrize('options,expect', [
125+
('', ['add', 'MixedSpam']),
126+
(':allowed-package-names: sphinx_automodapi', ['add', 'MixedSpam']),
127+
(':allowed-package-names: collections', ['OrderedDict']),
128+
(':allowed-package-names: sphinx_automodapi,collections',
129+
['add', 'MixedSpam', 'OrderedDict']),
130+
])
131+
def test_am_allowed_package_names(options, expect, tmpdir):
132+
"""
133+
Test that allowed_package_names is interpreted correctly.
134+
"""
135+
def mixed2noall(s):
136+
return s.replace('example_module.mixed', 'example_module.noall')
137+
138+
am_str = ams_to_asmry_str
139+
with open(tmpdir.join('index.rst').strpath, 'w') as f:
140+
f.write(mixed2noall(am_str).format(options=(' '+options if options else '')))
141+
142+
apidir = tmpdir.mkdir('api')
143+
with open(apidir.join('sphinx_automodapi.tests.example_module.noall.add.rst').strpath, 'w') as f:
144+
f.write(mixed2noall(ADD_RST))
145+
with open(apidir.join('sphinx_automodapi.tests.example_module.noall.MixedSpam.rst').strpath, 'w') as f:
146+
f.write(mixed2noall(MIXEDSPAM_RST))
147+
with open(apidir.join('sphinx_automodapi.tests.example_module.noall.OrderedDict.rst').strpath, 'w') as f:
148+
f.write(ORDEREDDICT_RST)
149+
150+
run_sphinx_in_tmpdir(tmpdir)
151+
152+
with open(tmpdir.join('index.rst.automodsumm').strpath) as f:
153+
result = f.read()
154+
155+
for x in expect:
156+
assert ' '+x in result
157+
158+
110159
PILOT_RST = """
111160
:orphan:
112161

sphinx_automodapi/tests/test_cases.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ def test_run_full_case(tmpdir, case_dir, parallel):
7474
'automodsumm_writereprocessed': True})
7575

7676
if os.path.basename(case_dir) in ('mixed_toplevel',
77-
'mixed_toplevel_all_objects'):
77+
'mixed_toplevel_all_objects',
78+
'allowed_names'):
7879
conf['extensions'].append('sphinx_automodapi.smart_resolver')
7980

8081
start_dir = os.path.abspath('.')

sphinx_automodapi/tests/test_utils.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,24 @@ def test_find_mod_objs():
2222
assert 'namedtuple' not in lnms
2323
assert 'collections.namedtuple' not in fqns
2424
assert namedtuple not in objs
25+
26+
27+
def test_find_mod_objs_with_list_of_modules():
28+
lnms, fqns, objs = find_mod_objs(
29+
'sphinx_automodapi.tests.test_utils', onlylocals=['sphinx_automodapi'])
30+
31+
assert namedtuple not in objs
32+
assert find_mod_objs in objs
33+
34+
lnms, fqns, objs = find_mod_objs(
35+
'sphinx_automodapi.tests.test_utils', onlylocals=['collections'])
36+
37+
assert namedtuple in objs
38+
assert find_mod_objs not in objs
39+
40+
lnms, fqns, objs = find_mod_objs(
41+
'sphinx_automodapi.tests.test_utils', onlylocals=['collections',
42+
'sphinx_automodapi'])
43+
44+
assert namedtuple in objs
45+
assert find_mod_objs in objs

sphinx_automodapi/utils.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import re
44
import os
55
from warnings import warn
6-
from distutils.version import LooseVersion
76

8-
from sphinx import __version__
97
from sphinx.ext.autosummary.generate import find_autosummary_in_docstring
108

119
__all__ = ['cleanup_whitespace',
@@ -58,9 +56,10 @@ def find_mod_objs(modname, onlylocals=False):
5856
----------
5957
modname : str
6058
The name of the module to search.
61-
onlylocals : bool
59+
onlylocals : bool or list
6260
If True, only attributes that are either members of `modname` OR one of
63-
its modules or subpackages will be included.
61+
its modules or subpackages will be included. If a list, only members
62+
of packages in the list are included. If `False`, selection is done.
6463
6564
Returns
6665
-------
@@ -82,10 +81,12 @@ def find_mod_objs(modname, onlylocals=False):
8281
__import__(modname)
8382
mod = sys.modules[modname]
8483

84+
# Note: use getattr instead of mod.__dict__[k] for modules that
85+
# define their own __getattr__ and __dir__.
8586
if hasattr(mod, '__all__'):
86-
pkgitems = [(k, mod.__dict__[k]) for k in mod.__all__]
87+
pkgitems = [(k, getattr(mod, k)) for k in mod.__all__]
8788
else:
88-
pkgitems = [(k, mod.__dict__[k]) for k in dir(mod) if k[0] != '_']
89+
pkgitems = [(k, getattr(mod, k)) for k in dir(mod) if k[0] != '_']
8990

9091
# filter out modules and pull the names and objs out
9192
ismodule = inspect.ismodule
@@ -101,6 +102,8 @@ def find_mod_objs(modname, onlylocals=False):
101102
fqnames.append(modname + '.' + lnm)
102103

103104
if onlylocals:
105+
if isinstance(onlylocals, (tuple, list)):
106+
modname = tuple(onlylocals)
104107
valids = [fqn.startswith(modname) for fqn in fqnames]
105108
localnames = [e for i, e in enumerate(localnames) if valids[i]]
106109
fqnames = [e for i, e in enumerate(fqnames) if valids[i]]

0 commit comments

Comments
 (0)