~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to utilities/format-imports

Merged fix-retest-colorize into redo-read-only-transactions-in-buildmaster, resolving several import conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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("([^. ]+)")
155
156
 
156
157
# Module docstrings are multiline (""") strings that are not indented and are
157
158
# followed at some point by an import .
285
286
 
286
287
    return imports
287
288
 
 
289
LOCAL_PACKAGES = (
 
290
    'canonical', 'lp', 'launchpad_loggerhead', 'devscripts',
 
291
    # database/* have some implicit relative imports.
 
292
    'fti', 'replication', 'preflight', 'security', 'upgrade',
 
293
    )
288
294
 
289
295
def format_imports(imports):
290
296
    """Group and order imports, return the new import statements."""
 
297
    early_section = {}
291
298
    standard_section = {}
292
299
    first_section = {}
293
300
    thirdparty_section = {}
294
301
    local_section = {}
295
302
    # Group modules into sections.
296
303
    for module, statement in imports.iteritems():
297
 
        module_base = module.split('.')[0]
 
304
        module_base = module_base_regex.findall(module)[0]
298
305
        comment = statement.comment
299
 
        if comment is not None and comment.startswith("# FIRST"):
 
306
        if module_base == '_pythonpath':
 
307
            early_section[module] = statement
 
308
        elif comment is not None and comment.startswith("# FIRST"):
300
309
            first_section[module] = statement
301
 
        elif module_base in ('canonical', 'lp'):
 
310
        elif module_base in LOCAL_PACKAGES:
302
311
            local_section[module] = statement
303
312
        elif module_base in python_standard_libs:
304
313
            standard_section[module] = statement
308
317
    all_import_lines = []
309
318
    # Sort within each section and generate statement strings.
310
319
    sections = (
 
320
        early_section,
311
321
        standard_section,
312
322
        first_section,
313
323
        thirdparty_section,
339
349
    imports_section = pyfile[import_start:import_end]
340
350
    imports = parse_import_statements(imports_section)
341
351
 
342
 
    if pyfile[import_end:import_end + 1] != '#':
 
352
    next_char = pyfile[import_end:import_end + 1]
 
353
 
 
354
    if next_char == '':
 
355
        number_of_newlines = 1
 
356
    elif next_char != '#':
343
357
        # Two newlines before anything but comments.
344
358
        number_of_newlines = 3
345
359
    else: