← Back to team overview

launchpad-dev team mailing list archive

format-imports script now in LP tree

 

Hi all,
the format-imports script which I used for converting the import statements to
the new style is now available in devel r11469 at utilities/format-imports.

You can type "utilities/format-imports --docstring | less" to read the
documentation but I pasted it here for your convenience.

Cheers,
Henning

= Usage =

format-imports <file or directory> ...

= Operation =

The script will process each filename on the command line. If the file is a
directory it recurses into it an process all *.py files found in the tree.
It will output the paths of all the files that have been changed.

For Launchpad it was applied to the "lib/canonical/launchpad" and the "lib/lp"
subtrees. Running it with those parameters on a freshly branched LP tree
should not produce any output, meaning that all the files in the tree should
be formatted correctly.

The script identifies the import section of each file as a block of lines
that start with "import" or "from" or are indented with at least one space or
are blank lines. Comment lines are also included if they are followed by an
import statement. An inital __future__ import and a module docstring are
explicitly skipped.

The import section is rewritten as three subsections, each separated by a
blank line. Any of the sections may be empty.
 1. Standard python library modules
 2. Import statements explicitly ordered to the top (see below)
 3. Third-party modules, meaning anything not fitting one of the other
    subsection criteria
 4. Local modules that begin with "canonical" or "lp".

Each section is sorted alphabetically by module name. Each module is put
on its own line, i.e.
{{{
  import os, sys
}}}
becomes
{{{
  import os
  import sys
}}}
Multiple import statements for the same module are conflated into one
statement, or two if the module was imported alongside an object inside it,
i.e.
{{{
  import sys
  from sys import stdin
}}}

Statements that import more than one objects are put on multiple lines in
list style, i.e.
{{{
  from sys import (
      stdin,
      stdout,
      )
}}}
Objects are sorted alphabetically and case-insensitively. One-object imports
are only formatted in this manner if the statement exceeds 78 characters in
length.

Comments stick with the import statement that followed them. Comments at the
end of one-line statements are moved to be be in front of it, .i.e.
{{{
  from sys import exit # Have a way out
}}}
becomes
{{{
  # Have a way out
  from sys import exit
}}}

= Format control =

Two special comments allow to control the operation of the formatter.

When an import statement is immediately preceded by a comment that starts
with the word "FIRST", it is placed into the second subsection (see above).

When the first import statement is directly preceded by a comment that starts
with the word "SKIP", the entire file is exempt from formatting.

= Known bugs =

Make sure to always check the result of the re-formatting to see if you have
been bitten by one of these.

Comments inside multi-line import statements break the formatter. A statement
like this will be ignored:
{{{
  from lp.app.interfaces import (
      # Don't do this.
      IMyInterface,
      IMyOtherInterface, # Don't do this either
      )
}}}
Actually, this will make the statement and all following to be ignored:
{{{
  from lp.app.interfaces import (
  # Breaks indentation rules anyway.
      IMyInterface,
      IMyOtherInterface,
      )
}}}

If a single-line statement has both a comment in front of it and at the end
of the line, only the end-line comment will survive. This could probably
easily be fixed to concatenate the too.
{{{
  # I am a gonner.
  from lp.app.interfaces import IMyInterface # I will survive!
}}}

Line continuation characters are recognized and resolved but
not re-introduced. This may leave the re-formatted text with a line that
is over the length limit.
{{{
    from lp.app.verylongnames.orverlydeep.modulestructure.leavenoroom
import object
}}}



Follow ups