22
22
from scanpydoc .elegant_typehints .return_tuple import process_docstring
23
23
24
24
25
- _testmod = sys .modules ["_testmod" ] = ModuleType ("_testmod" )
26
- _testmod .Class = type ("Class" , (), dict (__module__ = "_testmod" ))
27
- _testmod .SubCl = type ("SubCl" , (_testmod .Class ,), dict (__module__ = "_testmod" ))
28
- _testmod .Excep = type ("Excep" , (RuntimeError ,), dict (__module__ = "_testmod" ))
29
- _testmod .Excep2 = type ("Excep2" , (_testmod .Excep ,), dict (__module__ = "_testmod" ))
25
+ @pytest .fixture
26
+ def _testmod (make_module ):
27
+ return make_module (
28
+ "_testmod" ,
29
+ """\
30
+ class Class: pass
31
+ class SubCl(Class): pass
32
+ class Excep(RuntimeError): pass
33
+ class Excep2(Excep): pass
34
+ """ ,
35
+ )
30
36
31
37
32
38
@pytest .fixture
@@ -150,17 +156,17 @@ def test_literal(app):
150
156
)
151
157
152
158
153
- def test_qualname_overrides_class (app ):
159
+ def test_qualname_overrides_class (app , _testmod ):
154
160
assert _testmod .Class .__module__ == "_testmod"
155
161
assert _format_terse (_testmod .Class ) == ":py:class:`~test.Class`"
156
162
157
163
158
- def test_qualname_overrides_exception (app ):
164
+ def test_qualname_overrides_exception (app , _testmod ):
159
165
assert _testmod .Excep .__module__ == "_testmod"
160
166
assert _format_terse (_testmod .Excep ) == ":py:exc:`~test.Excep`"
161
167
162
168
163
- def test_qualname_overrides_recursive (app ):
169
+ def test_qualname_overrides_recursive (app , _testmod ):
164
170
assert _format_terse (t .Union [_testmod .Class , str ]) == (
165
171
r":py:class:`~test.Class`, :py:class:`str`"
166
172
)
@@ -172,7 +178,7 @@ def test_qualname_overrides_recursive(app):
172
178
)
173
179
174
180
175
- def test_fully_qualified (app ):
181
+ def test_fully_qualified (app , _testmod ):
176
182
assert _format_terse (t .Union [_testmod .Class , str ], True ) == (
177
183
r":py:class:`test.Class`, :py:class:`str`"
178
184
)
@@ -237,7 +243,7 @@ def test_typing_class_nested(app):
237
243
("autoexception" , "Excep" , "Excep2" ),
238
244
],
239
245
)
240
- def test_autodoc (app , direc , base , sub ):
246
+ def test_autodoc (app , _testmod , direc , base , sub ):
241
247
Path (app .srcdir , "index.rst" ).write_text (
242
248
f"""\
243
249
.. { direc } :: _testmod.{ sub }
@@ -252,6 +258,45 @@ def test_autodoc(app, direc, base, sub):
252
258
assert re .search (rf"Bases: <code[^>]*><span[^>]*>test\.{ base } " , out ), out
253
259
254
260
261
+ @pytest .mark .skipif (sys .version_info < (3 , 7 ), reason = "bpo-34776 only fixed on 3.7+" )
262
+ def test_fwd_ref (app , make_module ):
263
+ make_module (
264
+ "fwd_mod" ,
265
+ """\
266
+ from dataclasses import dataclass
267
+
268
+ @dataclass
269
+ class A:
270
+ b: 'B'
271
+
272
+ @dataclass
273
+ class B:
274
+ a: A
275
+ """ ,
276
+ )
277
+ Path (app .srcdir , "index.rst" ).write_text (
278
+ f"""\
279
+ .. autosummary::
280
+
281
+ fwd_mod.A
282
+ fwd_mod.B
283
+ """
284
+ )
285
+ app .setup_extension ("sphinx.ext.autosummary" )
286
+
287
+ app .build ()
288
+
289
+ out = Path (app .outdir , "index.html" ).read_text ()
290
+ warnings = [
291
+ w
292
+ for w in app ._warning .getvalue ().splitlines ()
293
+ if "Cannot treat a function defined as a local function" not in w
294
+ ]
295
+ assert not warnings , warnings
296
+ # TODO: actually reproduce #14
297
+ assert "fwd_mod.A" in out , out
298
+
299
+
255
300
@pytest .mark .parametrize (
256
301
"docstring" ,
257
302
[
0 commit comments