Skip to content

Commit 4575d5a

Browse files
committed
FIX: support python3.7
python/cpython#46 or bpo-29463 added docstring as a property to the module class that comes out of AST (so the free strings no longer appear an the first element in the parsed files).
1 parent 2f46ea3 commit 4575d5a

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

sphinx_gallery/py_source_parser.py

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,41 @@ def get_docstring_and_rest(filename):
4747
if not isinstance(node, ast.Module):
4848
raise TypeError("This function only supports modules. "
4949
"You provided {0}".format(node.__class__.__name__))
50-
if node.body and isinstance(node.body[0], ast.Expr) and \
51-
isinstance(node.body[0].value, ast.Str):
52-
docstring_node = node.body[0]
53-
docstring = docstring_node.value.s
54-
if hasattr(docstring, 'decode'): # python2.7
55-
docstring = docstring.decode('utf-8')
56-
# This get the content of the file after the docstring last line
57-
# Note: 'maxsplit' argument is not a keyword argument in python2
58-
rest = content.decode('utf-8').split('\n', docstring_node.lineno)[-1]
59-
return docstring, rest
60-
else:
50+
try:
51+
# in python 3.7 module knows it's docstring
52+
docstring = node.docstring
53+
# grab the rest of the file
54+
# in python 3.7 module knows it's docstring
55+
docstring = node.docstring
56+
# count the lines in the docstring. We have to do it this way instead
57+
# of looking at the line of the first element of the AST because there may
58+
# be comments before the first code that SG needs to capture.
59+
ds_lines = len(docstring.split('\n'))
60+
# if there is a coding line, this will be off by one
61+
if content.startswith(b'# -*- coding:'):
62+
ds_lines += 1
63+
# grab the rest of the file
64+
rest = '\n'.join(content.decode('utf-8').split('\n')[ds_lines:])
65+
66+
except AttributeError:
67+
# this block can be removed when python 3.6 support is dropped
68+
if node.body and isinstance(node.body[0], ast.Expr) and \
69+
isinstance(node.body[0].value, ast.Str):
70+
docstring_node = node.body[0]
71+
docstring = docstring_node.value.s
72+
if hasattr(docstring, 'decode'): # python2.7
73+
docstring = docstring.decode('utf-8')
74+
# This get the content of the file after the docstring last line
75+
# Note: 'maxsplit' argument is not a keyword argument in python2
76+
rest = content.decode('utf-8').split('\n', docstring_node.lineno)[-1]
77+
else:
78+
docstring, rest = '', ''
79+
80+
if not docstring :
6181
raise ValueError(('Could not find docstring in file "{0}". '
6282
'A docstring is required by sphinx-gallery')
6383
.format(filename))
84+
return docstring, rest
6485

6586

6687
def split_code_and_text_blocks(source_file):

0 commit comments

Comments
 (0)