mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #3540 from rayl/fix-3348
Fix #3348: Show decorators in literalinclude and viewcode directives
This commit is contained in:
commit
6fbc42115e
1
CHANGES
1
CHANGES
@ -90,6 +90,7 @@ Features added
|
||||
* HTML buildre uses experimental HTML5 writer if ``html_experimental_html5_builder`` is True
|
||||
and docutils 0.13 and newer is installed.
|
||||
* LaTeX macros to customize space before and after tables in PDF output (refs #3504)
|
||||
* #3348: Show decorators in literalinclude and viewcode directives
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -296,6 +296,7 @@ class ModuleAnalyzer(object):
|
||||
namespace = [] # type: List[unicode]
|
||||
stack = [] # type: List[Tuple[unicode, unicode, unicode, int]]
|
||||
indent = 0
|
||||
decopos = None
|
||||
defline = False
|
||||
expect_indent = False
|
||||
emptylines = 0
|
||||
@ -319,8 +320,12 @@ class ModuleAnalyzer(object):
|
||||
name = next(tokeniter)[1] # type: ignore
|
||||
namespace.append(name)
|
||||
fullname = '.'.join(namespace)
|
||||
stack.append((tok, fullname, spos[0], indent))
|
||||
stack.append((tok, fullname, decopos or spos[0], indent))
|
||||
defline = True
|
||||
decopos = None
|
||||
elif type == token.OP and tok == '@':
|
||||
if decopos is None:
|
||||
decopos = spos[0]
|
||||
elif type == token.INDENT:
|
||||
expect_indent = False
|
||||
indent += 1
|
||||
|
16
tests/roots/test-directive-code/py-decorators.inc
Normal file
16
tests/roots/test-directive-code/py-decorators.inc
Normal file
@ -0,0 +1,16 @@
|
||||
# Literally included file using Python highlighting
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
@class_decorator
|
||||
@other_decorator()
|
||||
class TheClass(object):
|
||||
|
||||
@method_decorator
|
||||
@other_decorator()
|
||||
def the_method():
|
||||
pass
|
||||
|
||||
@function_decorator
|
||||
@other_decorator()
|
||||
def the_function():
|
||||
pass
|
17
tests/roots/test-directive-code/py-decorators.rst
Normal file
17
tests/roots/test-directive-code/py-decorators.rst
Normal file
@ -0,0 +1,17 @@
|
||||
py-decorators
|
||||
=============
|
||||
|
||||
Various decorators
|
||||
------------------
|
||||
|
||||
.. literalinclude:: py-decorators.inc
|
||||
:name: literal_include_pydecorators_1
|
||||
:pyobject: TheClass
|
||||
|
||||
.. literalinclude:: py-decorators.inc
|
||||
:name: literal_include_pydecorators_2
|
||||
:pyobject: TheClass.the_method
|
||||
|
||||
.. literalinclude:: py-decorators.inc
|
||||
:name: literal_include_pydecorators_3
|
||||
:pyobject: the_function
|
@ -2,6 +2,10 @@
|
||||
mod1
|
||||
"""
|
||||
|
||||
def decorator(f):
|
||||
return f
|
||||
|
||||
@decorator
|
||||
def func1(a, b):
|
||||
"""
|
||||
this is func1
|
||||
@ -9,6 +13,7 @@ def func1(a, b):
|
||||
return a, b
|
||||
|
||||
|
||||
@decorator
|
||||
class Class1(object):
|
||||
"""
|
||||
this is Class1
|
||||
|
@ -2,6 +2,10 @@
|
||||
mod2
|
||||
"""
|
||||
|
||||
def decorator(f):
|
||||
return f
|
||||
|
||||
@decorator
|
||||
def func2(a, b):
|
||||
"""
|
||||
this is func2
|
||||
@ -9,6 +13,7 @@ def func2(a, b):
|
||||
return a, b
|
||||
|
||||
|
||||
@decorator
|
||||
class Class2(object):
|
||||
"""
|
||||
this is Class2
|
||||
|
@ -454,3 +454,45 @@ def test_literalinclude_classes(app, status, warning):
|
||||
assert len(literalinclude) > 0
|
||||
assert 'bar baz' == literalinclude[0].get('classes')
|
||||
assert 'literal_include' == literalinclude[0].get('names')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('xml', testroot='directive-code')
|
||||
def test_literalinclude_pydecorators(app, status, warning):
|
||||
app.builder.build(['py-decorators'])
|
||||
et = etree_parse(app.outdir / 'py-decorators.xml')
|
||||
secs = et.findall('./section/section')
|
||||
|
||||
literal_include = secs[0].findall('literal_block')
|
||||
assert len(literal_include) == 3
|
||||
|
||||
actual = literal_include[0].text
|
||||
expect = (
|
||||
'@class_decorator\n'
|
||||
'@other_decorator()\n'
|
||||
'class TheClass(object):\n'
|
||||
'\n'
|
||||
' @method_decorator\n'
|
||||
' @other_decorator()\n'
|
||||
' def the_method():\n'
|
||||
' pass\n'
|
||||
)
|
||||
assert actual == expect
|
||||
|
||||
actual = literal_include[1].text
|
||||
expect = (
|
||||
' @method_decorator\n'
|
||||
' @other_decorator()\n'
|
||||
' def the_method():\n'
|
||||
' pass\n'
|
||||
)
|
||||
assert actual == expect
|
||||
|
||||
actual = literal_include[2].text
|
||||
expect = (
|
||||
'@function_decorator\n'
|
||||
'@other_decorator()\n'
|
||||
'def the_function():\n'
|
||||
' pass\n'
|
||||
)
|
||||
assert actual == expect
|
||||
|
||||
|
@ -30,6 +30,7 @@ def test_viewcode(app, status, warning):
|
||||
assert result.count('href="_modules/spam/mod2.html#func2"') == 2
|
||||
assert result.count('href="_modules/spam/mod1.html#Class1"') == 2
|
||||
assert result.count('href="_modules/spam/mod2.html#Class2"') == 2
|
||||
assert result.count('@decorator') == 1
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='ext-viewcode', tags=['test_linkcode'])
|
||||
|
Loading…
Reference in New Issue
Block a user