Skip to content

Commit 71eba3c

Browse files
committed
Add test for missing object raises warning on import
1 parent 9a6d33c commit 71eba3c

File tree

5 files changed

+260
-0
lines changed

5 files changed

+260
-0
lines changed

tests/python/pymissing_import/conf.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
templates_path = ["_templates"]
2+
source_suffix = ".rst"
3+
master_doc = "index"
4+
project = "pymissing_import"
5+
author = "Arwed Starke"
6+
version = "0.1"
7+
release = "0.1"
8+
language = "en"
9+
exclude_patterns = ["_build"]
10+
pygments_style = "sphinx"
11+
html_theme = "alabaster"
12+
extensions = ["sphinx.ext.autodoc", "autoapi.extension"]
13+
autoapi_dirs = ["example"]
14+
autoapi_python_class_content = "both"
15+
autoapi_generate_api_docs = False
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
"""Example module
2+
3+
This is a description
4+
"""
5+
6+
from dataclasses import dataclass
7+
from functools import cached_property
8+
9+
A_TUPLE = ("a", "b")
10+
"""A tuple to be rendered as a tuple."""
11+
A_LIST = ["c", "d"]
12+
"""A list to be rendered as a list."""
13+
14+
15+
class Foo:
16+
"""Can we parse arguments from the class docstring?
17+
18+
:param attr: Set an attribute.
19+
:type attr: str
20+
"""
21+
22+
class_var = 42 #: Class var docstring
23+
24+
another_class_var = 42
25+
"""Another class var docstring"""
26+
27+
class Meta:
28+
"""A nested class just to test things out"""
29+
30+
@classmethod
31+
def foo():
32+
"""The foo class method"""
33+
return True
34+
35+
def __init__(self, attr):
36+
"""Constructor docstring"""
37+
self.attr = attr
38+
self.attr2 = attr
39+
"""This is the docstring of an instance attribute.
40+
41+
:type: str
42+
"""
43+
44+
@property
45+
def attr(self):
46+
return 5
47+
48+
@attr.setter
49+
def attr(self, value):
50+
pass
51+
52+
@property
53+
def property_simple(self) -> int:
54+
"""This property should parse okay."""
55+
return 42
56+
57+
@cached_property
58+
def my_cached_property(self) -> int:
59+
"""This cached property should be a property."""
60+
return 42
61+
62+
def method_okay(self, foo=None, bar=None):
63+
"""This method should parse okay"""
64+
return True
65+
66+
def method_multiline(self, foo=None, bar=None, baz=None):
67+
"""This is on multiple lines, but should parse okay too
68+
69+
pydocstyle gives us lines of source. Test if this means that multiline
70+
definitions are covered in the way we're anticipating here
71+
"""
72+
return True
73+
74+
def method_tricky(self, foo=None, bar=dict(foo=1, bar=2)):
75+
"""This will likely fail our argument testing
76+
77+
We parse naively on commas, so the nested dictionary will throw this off
78+
"""
79+
return True
80+
81+
def method_sphinx_docs(self, foo, bar=0):
82+
"""This method is documented with sphinx style docstrings.
83+
84+
:param foo: The first argument.
85+
:type foo: int
86+
87+
:param int bar: The second argument.
88+
89+
:returns: The sum of foo and bar.
90+
:rtype: int
91+
"""
92+
return foo + bar
93+
94+
def method_google_docs(self, foo, bar=0):
95+
"""This method is documented with google style docstrings.
96+
97+
Args:
98+
foo (int): The first argument.
99+
bar (int): The second argument.
100+
101+
Returns:
102+
int: The sum of foo and bar.
103+
"""
104+
return foo + bar
105+
106+
def method_sphinx_unicode(self):
107+
"""This docstring uses unicodé.
108+
109+
:returns: A string.
110+
:rtype: str
111+
"""
112+
return "sphinx"
113+
114+
def method_google_unicode(self):
115+
"""This docstring uses unicodé.
116+
117+
Returns:
118+
str: A string.
119+
"""
120+
return "google"
121+
122+
123+
Foo.bar = "dinglebop"
124+
125+
126+
def decorator_okay(func):
127+
"""This decorator should parse okay."""
128+
129+
def wrapper(*args, **kwargs):
130+
return func(*args, **kwargs)
131+
132+
return wrapper
133+
134+
135+
class Bar(Foo):
136+
def method_okay(self, foo=None, bar=None):
137+
pass
138+
139+
140+
class ClassWithNoInit:
141+
pass
142+
143+
144+
class One:
145+
"""One."""
146+
147+
def __init__(self):
148+
"""One __init__."""
149+
super().__init__()
150+
151+
152+
class MultilineOne(One):
153+
"""This is a naughty summary line
154+
that exists on two lines."""
155+
156+
157+
class Two(One):
158+
"""Two."""
159+
160+
161+
class Three:
162+
__init__ = Two.__init__
163+
164+
165+
def fn_with_long_sig(
166+
this,
167+
*,
168+
function=None,
169+
has=True,
170+
quite=True,
171+
a,
172+
long,
173+
signature,
174+
many,
175+
keyword,
176+
arguments,
177+
):
178+
"""A function with a long signature."""
179+
180+
181+
TYPED_DATA: int = 1
182+
"""This is TYPED_DATA."""
183+
184+
185+
@dataclass
186+
class TypedAttrs:
187+
one: str
188+
"""This is TypedAttrs.one."""
189+
two: int = 1
190+
"""This is TypedAttrs.two."""
191+
192+
193+
class TypedClassInit:
194+
"""This is TypedClassInit."""
195+
196+
def __init__(self, one: int = 1) -> None:
197+
self._one = one
198+
199+
def typed_method(self, two: int) -> int:
200+
"""This is TypedClassInit.typed_method."""
201+
return self._one + two
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.. pyexample documentation master file, created by
2+
sphinx-quickstart on Fri May 29 13:34:37 2015.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
Welcome to pyexample's documentation!
7+
=====================================
8+
9+
.. toctree::
10+
:glob:
11+
12+
manualapi
13+
14+
15+
Indices and tables
16+
==================
17+
18+
* :ref:`genindex`
19+
* :ref:`modindex`
20+
* :ref:`search`
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Autodoc Directives
2+
==================
3+
4+
.. autoapimodule:: example
5+
:members:
6+
7+
8+
.. autoapimodule:: nonexisting_module
9+
:members:

tests/python/test_pyintegration.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,21 @@ def test_nothing_to_render_raises_warning(builder, caplog):
13291329
)
13301330

13311331

1332+
def test_missing_object_raises_warning(builder, caplog):
1333+
caplog.set_level(logging.WARNING, logger="autoapi._mapper")
1334+
if sphinx_version >= (8, 1):
1335+
status = builder("pymissing_import", warningiserror=True)
1336+
assert status
1337+
else:
1338+
with pytest.raises(sphinx.errors.SphinxWarning):
1339+
builder("pymissing_import", warningiserror=True)
1340+
1341+
assert any(
1342+
"Failed to import module 'nonexisting_module'" in record.message
1343+
for record in caplog.records
1344+
)
1345+
1346+
13321347
class TestStdLib:
13331348
"""Check that modules with standard library names are still documented."""
13341349

0 commit comments

Comments
 (0)