152
152
comment_regex = re.compile(
153
153
"(?P<comment>(^#.+\n)+)(^import|^from) +(?P<module>[a-zA-Z0-9_.]+)", re.M)
154
154
split_regex = re.compile(",\s*")
155
module_base_regex = re.compile("([^. ]+)")
157
156
# Module docstrings are multiline (""") strings that are not indented and are
158
157
# followed at some point by an import .
290
'canonical', 'lp', 'launchpad_loggerhead', 'devscripts',
291
# database/* have some implicit relative imports.
292
'fti', 'replication', 'preflight', 'security', 'upgrade',
295
289
def format_imports(imports):
296
290
"""Group and order imports, return the new import statements."""
298
291
standard_section = {}
299
292
first_section = {}
300
293
thirdparty_section = {}
301
294
local_section = {}
302
295
# Group modules into sections.
303
296
for module, statement in imports.iteritems():
304
module_base = module_base_regex.findall(module)[0]
297
module_base = module.split('.')[0]
305
298
comment = statement.comment
306
if module_base == '_pythonpath':
307
early_section[module] = statement
308
elif comment is not None and comment.startswith("# FIRST"):
299
if comment is not None and comment.startswith("# FIRST"):
309
300
first_section[module] = statement
310
elif module_base in LOCAL_PACKAGES:
301
elif module_base in ('canonical', 'lp'):
311
302
local_section[module] = statement
312
303
elif module_base in python_standard_libs:
313
304
standard_section[module] = statement
349
339
imports_section = pyfile[import_start:import_end]
350
340
imports = parse_import_statements(imports_section)
352
next_char = pyfile[import_end:import_end + 1]
355
number_of_newlines = 1
356
elif next_char != '#':
342
if pyfile[import_end:import_end + 1] != '#':
357
343
# Two newlines before anything but comments.
358
344
number_of_newlines = 3