26
26
27
27
# Functions and classes
28
28
class ApiDocWriter (object ):
29
- ''' Class for automatic detection and parsing of API docs
30
- to Sphinx-parsable reST format'''
29
+ """ Class for automatic detection and parsing of API docs
30
+ to Sphinx-parsable reST format"""
31
31
32
32
# only separating first two levels
33
- rst_section_levels = ['*' , '=' , '-' , '~' , '^' ]
33
+ rst_section_levels = ["*" , "=" , "-" , "~" , "^" ]
34
34
35
35
def __init__ (
36
- self ,
37
- package_name ,
38
- rst_extension = ' .rst' ,
39
- package_skip_patterns = None ,
40
- module_skip_patterns = None ,
36
+ self ,
37
+ package_name ,
38
+ rst_extension = " .rst" ,
39
+ package_skip_patterns = None ,
40
+ module_skip_patterns = None ,
41
41
):
42
- ''' Initialize package for parsing
42
+ """ Initialize package for parsing
43
43
44
44
Parameters
45
45
----------
@@ -64,11 +64,11 @@ def __init__(
64
64
``.util.console``
65
65
If is None, gives default. Default is:
66
66
['\.setup$', '\._']
67
- '''
67
+ """
68
68
if package_skip_patterns is None :
69
- package_skip_patterns = [' \\ .tests$' ]
69
+ package_skip_patterns = [" \\ .tests$" ]
70
70
if module_skip_patterns is None :
71
- module_skip_patterns = [' \\ .setup$' , ' \\ ._' ]
71
+ module_skip_patterns = [" \\ .setup$" , " \\ ._" ]
72
72
self .package_name = package_name
73
73
self .rst_extension = rst_extension
74
74
self .package_skip_patterns = package_skip_patterns
@@ -78,7 +78,7 @@ def get_package_name(self):
78
78
return self ._package_name
79
79
80
80
def set_package_name (self , package_name ):
81
- ''' Set package_name
81
+ """ Set package_name
82
82
83
83
>>> docwriter = ApiDocWriter('sphinx')
84
84
>>> import sphinx
@@ -88,33 +88,34 @@ def set_package_name(self, package_name):
88
88
>>> import docutils
89
89
>>> docwriter.root_path == docutils.__path__[0]
90
90
True
91
- '''
91
+ """
92
92
# It's also possible to imagine caching the module parsing here
93
93
self ._package_name = package_name
94
94
self .root_module = __import__ (package_name )
95
95
self .root_path = self .root_module .__path__ [0 ]
96
96
self .written_modules = None
97
97
98
- package_name = property (get_package_name , set_package_name , None ,
99
- 'get/set package_name' )
98
+ package_name = property (
99
+ get_package_name , set_package_name , None , "get/set package_name"
100
+ )
100
101
101
102
def _get_object_name (self , line ):
102
- ''' Get second token in line
103
+ """ Get second token in line
103
104
>>> docwriter = ApiDocWriter('sphinx')
104
105
>>> docwriter._get_object_name(" def func(): ")
105
106
u'func'
106
107
>>> docwriter._get_object_name(" class Klass(object): ")
107
108
'Klass'
108
109
>>> docwriter._get_object_name(" class Klass: ")
109
110
'Klass'
110
- '''
111
- name = line .split ()[1 ].split ('(' )[0 ].strip ()
111
+ """
112
+ name = line .split ()[1 ].split ("(" )[0 ].strip ()
112
113
# in case we have classes which are not derived from object
113
114
# ie. old style classes
114
- return name .rstrip (':' )
115
+ return name .rstrip (":" )
115
116
116
117
def _uri2path (self , uri ):
117
- ''' Convert uri to absolute filepath
118
+ """ Convert uri to absolute filepath
118
119
119
120
Parameters
120
121
----------
@@ -140,53 +141,53 @@ def _uri2path(self, uri):
140
141
True
141
142
>>> docwriter._uri2path('sphinx.does_not_exist')
142
143
143
- '''
144
+ """
144
145
if uri == self .package_name :
145
- return os .path .join (self .root_path , ' __init__.py' )
146
- path = uri .replace ('.' , os .path .sep )
147
- path = path .replace (self .package_name + os .path .sep , '' )
146
+ return os .path .join (self .root_path , " __init__.py" )
147
+ path = uri .replace ("." , os .path .sep )
148
+ path = path .replace (self .package_name + os .path .sep , "" )
148
149
path = os .path .join (self .root_path , path )
149
150
# XXX maybe check for extensions as well?
150
- if os .path .exists (path + ' .py' ): # file
151
- path += ' .py'
152
- elif os .path .exists (os .path .join (path , ' __init__.py' )):
153
- path = os .path .join (path , ' __init__.py' )
151
+ if os .path .exists (path + " .py" ): # file
152
+ path += " .py"
153
+ elif os .path .exists (os .path .join (path , " __init__.py" )):
154
+ path = os .path .join (path , " __init__.py" )
154
155
else :
155
156
return None
156
157
return path
157
158
158
159
def _path2uri (self , dirpath ):
159
- ''' Convert directory path to uri '''
160
+ """ Convert directory path to uri """
160
161
relpath = dirpath .replace (self .root_path , self .package_name )
161
162
if relpath .startswith (os .path .sep ):
162
163
relpath = relpath [1 :]
163
- return relpath .replace (os .path .sep , '.' )
164
+ return relpath .replace (os .path .sep , "." )
164
165
165
166
def _parse_module (self , uri ):
166
- ''' Parse module defined in *uri* '''
167
+ """ Parse module defined in *uri* """
167
168
filename = self ._uri2path (uri )
168
169
if filename is None :
169
170
# nothing that we could handle here.
170
171
return ([], [])
171
- f = open (filename , 'rt' )
172
+ f = open (filename , "rt" )
172
173
functions , classes = self ._parse_lines (f )
173
174
f .close ()
174
175
return functions , classes
175
176
176
177
def _parse_lines (self , linesource ):
177
- ''' Parse lines of text for functions and classes '''
178
+ """ Parse lines of text for functions and classes """
178
179
functions = []
179
180
classes = []
180
181
for line in linesource :
181
- if line .startswith (' def ' ) and line .count ('(' ):
182
+ if line .startswith (" def " ) and line .count ("(" ):
182
183
# exclude private stuff
183
184
name = self ._get_object_name (line )
184
- if not name .startswith ('_' ):
185
+ if not name .startswith ("_" ):
185
186
functions .append (name )
186
- elif line .startswith (' class ' ):
187
+ elif line .startswith (" class " ):
187
188
# exclude private stuff
188
189
name = self ._get_object_name (line )
189
- if not name .startswith ('_' ):
190
+ if not name .startswith ("_" ):
190
191
classes .append (name )
191
192
else :
192
193
pass
@@ -195,7 +196,7 @@ def _parse_lines(self, linesource):
195
196
return functions , classes
196
197
197
198
def generate_api_doc (self , uri ):
198
- ''' Make autodoc documentation template string for a module
199
+ """ Make autodoc documentation template string for a module
199
200
200
201
Parameters
201
202
----------
@@ -206,71 +207,72 @@ def generate_api_doc(self, uri):
206
207
-------
207
208
S : string
208
209
Contents of API doc
209
- '''
210
+ """
210
211
# get the names of all classes and functions
211
212
functions , classes = self ._parse_module (uri )
212
213
if not len (functions ) and not len (classes ):
213
- print ((' WARNING: Empty -' , uri )) # dbg
214
- return ''
214
+ print ((" WARNING: Empty -" , uri )) # dbg
215
+ return ""
215
216
216
217
# Make a shorter version of the uri that omits the package name for
217
218
# titles
218
- uri_short = re .sub (r' ^%s\.' % self .package_name , '' , uri )
219
+ uri_short = re .sub (r" ^%s\." % self .package_name , "" , uri )
219
220
220
- ad = ' .. AUTO-GENERATED FILE -- DO NOT EDIT!\n \n '
221
+ ad = " .. AUTO-GENERATED FILE -- DO NOT EDIT!\n \n "
221
222
222
223
chap_title = uri_short
223
- ad += (chap_title + '\n ' +
224
- self .rst_section_levels [1 ] * len (chap_title ) + '\n \n ' )
224
+ ad += chap_title + "\n " + self .rst_section_levels [1 ] * len (chap_title ) + "\n \n "
225
225
226
226
# Set the chapter title to read 'module' for all modules except for the
227
227
# main packages
228
- if '.' in uri :
229
- title = ' Module: :mod:`' + uri_short + '`'
228
+ if "." in uri :
229
+ title = " Module: :mod:`" + uri_short + "`"
230
230
else :
231
- title = ' :mod:`' + uri_short + '`'
232
- ad += title + ' \n ' + self .rst_section_levels [2 ] * len (title )
231
+ title = " :mod:`" + uri_short + "`"
232
+ ad += title + " \n " + self .rst_section_levels [2 ] * len (title )
233
233
234
234
if len (classes ):
235
- ad += ' \n Inheritance diagram for ``%s``:\n \n ' % uri
236
- ad += ' .. inheritance-diagram:: %s \n ' % uri
237
- ad += ' :parts: 2\n '
235
+ ad += " \n Inheritance diagram for ``%s``:\n \n " % uri
236
+ ad += " .. inheritance-diagram:: %s \n " % uri
237
+ ad += " :parts: 2\n "
238
238
239
- ad += ' \n .. automodule:: ' + uri + ' \n '
240
- ad += ' \n .. currentmodule:: ' + uri + ' \n '
239
+ ad += " \n .. automodule:: " + uri + " \n "
240
+ ad += " \n .. currentmodule:: " + uri + " \n "
241
241
multi_class = len (classes ) > 1
242
242
multi_fx = len (functions ) > 1
243
243
if multi_class :
244
- ad += '\n ' + 'Classes' + '\n ' + \
245
- self .rst_section_levels [2 ] * 7 + '\n '
244
+ ad += "\n " + "Classes" + "\n " + self .rst_section_levels [2 ] * 7 + "\n "
246
245
elif len (classes ) and multi_fx :
247
- ad += '\n ' + 'Class' + '\n ' + \
248
- self .rst_section_levels [2 ] * 5 + '\n '
246
+ ad += "\n " + "Class" + "\n " + self .rst_section_levels [2 ] * 5 + "\n "
249
247
for c in classes :
250
- ad += '\n :class:`' + c + '`\n ' \
251
- + self .rst_section_levels [multi_class + 2 ] * \
252
- (len (c ) + 9 ) + '\n \n '
253
- ad += '\n .. autoclass:: ' + c + '\n '
248
+ ad += (
249
+ "\n :class:`"
250
+ + c
251
+ + "`\n "
252
+ + self .rst_section_levels [multi_class + 2 ] * (len (c ) + 9 )
253
+ + "\n \n "
254
+ )
255
+ ad += "\n .. autoclass:: " + c + "\n "
254
256
# must NOT exclude from index to keep cross-refs working
255
- ad += ' :members:\n ' \
256
- ' :undoc-members:\n ' \
257
- ' :show-inheritance:\n ' \
258
- ' :inherited-members:\n ' \
259
- '\n ' \
260
- ' .. automethod:: __init__\n '
257
+ ad += (
258
+ " :members:\n "
259
+ " :undoc-members:\n "
260
+ " :show-inheritance:\n "
261
+ " :inherited-members:\n "
262
+ "\n "
263
+ " .. automethod:: __init__\n "
264
+ )
261
265
if multi_fx :
262
- ad += '\n ' + 'Functions' + '\n ' + \
263
- self .rst_section_levels [2 ] * 9 + '\n \n '
266
+ ad += "\n " + "Functions" + "\n " + self .rst_section_levels [2 ] * 9 + "\n \n "
264
267
elif len (functions ) and multi_class :
265
- ad += '\n ' + 'Function' + '\n ' + \
266
- self .rst_section_levels [2 ] * 8 + '\n \n '
268
+ ad += "\n " + "Function" + "\n " + self .rst_section_levels [2 ] * 8 + "\n \n "
267
269
for f in functions :
268
270
# must NOT exclude from index to keep cross-refs working
269
- ad += ' \n .. autofunction:: ' + uri + '.' + f + ' \n \n '
271
+ ad += " \n .. autofunction:: " + uri + "." + f + " \n \n "
270
272
return ad
271
273
272
274
def _survives_exclude (self , matchstr , match_type ):
273
- ''' Returns True if *matchstr* does not match patterns
275
+ """ Returns True if *matchstr* does not match patterns
274
276
275
277
``self.package_name`` removed from front of string if present
276
278
@@ -289,10 +291,10 @@ def _survives_exclude(self, matchstr, match_type):
289
291
>>> dw.module_skip_patterns.append('^\\ .badmod$')
290
292
>>> dw._survives_exclude('sphinx.badmod', 'module')
291
293
False
292
- '''
293
- if match_type == ' module' :
294
+ """
295
+ if match_type == " module" :
294
296
patterns = self .module_skip_patterns
295
- elif match_type == ' package' :
297
+ elif match_type == " package" :
296
298
patterns = self .package_skip_patterns
297
299
else :
298
300
raise ValueError ('Cannot interpret match type "%s"' % match_type )
@@ -312,7 +314,7 @@ def _survives_exclude(self, matchstr, match_type):
312
314
return True
313
315
314
316
def discover_modules (self ):
315
- ''' Return module sequence discovered from ``self.package_name``
317
+ """ Return module sequence discovered from ``self.package_name``
316
318
317
319
318
320
Parameters
@@ -334,25 +336,27 @@ def discover_modules(self):
334
336
>>> 'sphinx.util' in dw.discover_modules()
335
337
False
336
338
>>>
337
- '''
339
+ """
338
340
modules = []
339
341
# raw directory parsing
340
342
for dirpath , dirnames , filenames in os .walk (self .root_path ):
341
343
# Check directory names for packages
342
344
root_uri = self ._path2uri (os .path .join (self .root_path , dirpath ))
343
345
for dirname in dirnames [:]: # copy list - we modify inplace
344
- package_uri = '.' .join ((root_uri , dirname ))
345
- if (self ._uri2path (package_uri )
346
- and self ._survives_exclude (package_uri , 'package' )):
346
+ package_uri = "." .join ((root_uri , dirname ))
347
+ if self ._uri2path (package_uri ) and self ._survives_exclude (
348
+ package_uri , "package"
349
+ ):
347
350
modules .append (package_uri )
348
351
else :
349
352
dirnames .remove (dirname )
350
353
# Check filenames for modules
351
354
for filename in filenames :
352
355
module_name = filename [:- 3 ]
353
- module_uri = '.' .join ((root_uri , module_name ))
354
- if (self ._uri2path (module_uri )
355
- and self ._survives_exclude (module_uri , 'module' )):
356
+ module_uri = "." .join ((root_uri , module_name ))
357
+ if self ._uri2path (module_uri ) and self ._survives_exclude (
358
+ module_uri , "module"
359
+ ):
356
360
modules .append (module_uri )
357
361
# print sorted(modules) #dbg
358
362
return sorted (modules )
@@ -366,7 +370,7 @@ def write_modules_api(self, modules, outdir):
366
370
continue
367
371
# write out to file
368
372
outfile = os .path .join (outdir , m + self .rst_extension )
369
- fileobj = open (outfile , 'wt' )
373
+ fileobj = open (outfile , "wt" )
370
374
fileobj .write (api_str )
371
375
fileobj .close ()
372
376
written_modules .append (m )
@@ -395,7 +399,7 @@ def write_api_docs(self, outdir):
395
399
modules = self .discover_modules ()
396
400
self .write_modules_api (modules , outdir )
397
401
398
- def write_index (self , outdir , froot = ' gen' , relative_to = None ):
402
+ def write_index (self , outdir , froot = " gen" , relative_to = None ):
399
403
"""Make a reST API index file from written files
400
404
401
405
Parameters
@@ -414,18 +418,18 @@ def write_index(self, outdir, froot='gen', relative_to=None):
414
418
leave path as it is.
415
419
"""
416
420
if self .written_modules is None :
417
- raise ValueError (' No modules written' )
421
+ raise ValueError (" No modules written" )
418
422
# Get full filename path
419
423
path = os .path .join (outdir , froot + self .rst_extension )
420
424
# Path written into index is relative to rootpath
421
425
if relative_to is not None :
422
- relpath = outdir .replace (relative_to + os .path .sep , '' )
426
+ relpath = outdir .replace (relative_to + os .path .sep , "" )
423
427
else :
424
428
relpath = outdir
425
- idx = open (path , 'wt' )
429
+ idx = open (path , "wt" )
426
430
w = idx .write
427
- w (' .. AUTO-GENERATED FILE -- DO NOT EDIT!\n \n ' )
428
- w (' .. toctree::\n \n ' )
431
+ w (" .. AUTO-GENERATED FILE -- DO NOT EDIT!\n \n " )
432
+ w (" .. toctree::\n \n " )
429
433
for f in self .written_modules :
430
- w (' %s\n ' % os .path .join (relpath , f ))
434
+ w (" %s\n " % os .path .join (relpath , f ))
431
435
idx .close ()
0 commit comments