From 0215b1fb108ab3a78af41375c69eac84722022c1 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 29 Mar 2015 10:31:26 +0900 Subject: [PATCH] Fix #1789 `:pyobject:` option of `literalinclude` directive includes following lines after definitions --- CHANGES | 3 +++ sphinx/pycode/__init__.py | 17 ++++++++++++++--- tests/roots/test-directive-code/literal.inc | 1 + tests/test_directive_code.py | 9 ++++++--- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 546e06a74..1dddeff0f 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,9 @@ Features added Bugs fixed ---------- +* #1789: ``:pyobject:`` option of ``literalinclude`` directive includes following + lines after class definitions + Documentation ------------- diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index ec05c7bf7..57707e9d0 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -10,6 +10,7 @@ """ from __future__ import print_function +import re import sys from os import path @@ -45,6 +46,8 @@ number2name.update(token.tok_name) _eq = nodes.Leaf(token.EQUAL, '=') +emptyline_re = re.compile('^\s*(#.*)?$') + class AttrDocVisitor(nodes.NodeVisitor): """ @@ -289,8 +292,9 @@ class ModuleAnalyzer(object): indent = 0 defline = False expect_indent = False + emptylines = 0 - def tokeniter(ignore = (token.COMMENT, token.NL)): + def tokeniter(ignore = (token.COMMENT,)): for tokentup in self.tokens: if tokentup[0] not in ignore: yield tokentup @@ -303,7 +307,7 @@ class ModuleAnalyzer(object): dtype, fullname, startline, _ = stack.pop() endline = epos[0] namespace.pop() - result[fullname] = (dtype, startline, endline) + result[fullname] = (dtype, startline, endline - emptylines) expect_indent = False if tok in ('def', 'class'): name = next(tokeniter)[1] @@ -322,7 +326,7 @@ class ModuleAnalyzer(object): dtype, fullname, startline, _ = stack.pop() endline = spos[0] namespace.pop() - result[fullname] = (dtype, startline, endline) + result[fullname] = (dtype, startline, endline - emptylines) elif type == token.NEWLINE: # if this line contained a definition, expect an INDENT # to start the suite; if there is no such INDENT @@ -330,6 +334,13 @@ class ModuleAnalyzer(object): if defline: defline = False expect_indent = True + emptylines = 0 + elif type == token.NL: + # count up if line is empty or comment only + if emptyline_re.match(line): + emptylines += 1 + else: + emptylines = 0 self.tags = result return result diff --git a/tests/roots/test-directive-code/literal.inc b/tests/roots/test-directive-code/literal.inc index 694f15ed9..a590f557b 100644 --- a/tests/roots/test-directive-code/literal.inc +++ b/tests/roots/test-directive-code/literal.inc @@ -10,4 +10,5 @@ class Bar: def baz(): pass +# comment after Bar class definition def bar(): pass diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py index ba4687cc0..c09f97986 100644 --- a/tests/test_directive_code.py +++ b/tests/test_directive_code.py @@ -116,7 +116,8 @@ def test_literal_include_linenos(app, status, warning): '10\n' '11\n' '12\n' - '13') + '13\n' + '14') assert linenos in html @@ -138,7 +139,8 @@ def test_literal_include_lineno_start(app, status, warning): '209\n' '210\n' '211\n' - '212') + '212\n' + '213') assert linenos in html @@ -168,7 +170,8 @@ def test_literal_include_lineno_match(app, status, warning): '10\n' '11\n' '12\n' - '13') + '13\n' + '14') assert start_after in html